IBM Support

CL新增字符串处理内建函数介绍

Technical Blog Post


Abstract

CL新增字符串处理内建函数介绍

Body

IBM 给 CL 编程语言新增了一组用于字符串处理的内建函数,让我们先睹为快吧!

 

首先是一组 TRIM 函数:%TRIM,%TRIML,%TRIMR。

先上例子:

DCL VAR(&FIRSTNAME) TYPE(*CHAR) VALUE('   JOHN  ') 

DCL VAR(&LASTNAME) TYPE(*CHAR) VALUE('   SMITH  ') 

DCL VAR(&NAME) TYPE(*CHAR) LEN(10) 

/* &NAME will have the value 'JOHN SMITH' */

CHGVAR VAR(&NAME) VALUE(%TRIM(&FIRSTNAME) *BCAT %TRIM(&LASTNAME))

 

是的,正如你所见,%TRIM 可以去掉字符串首尾的空格。感觉还差点意思,再看看下面这个例子。

DCL VAR(&NAME) TYPE(*CHAR) LEN(10) VALUE('*+12345   ') 

DCL VAR(&TCHAR) TYPE(*CHAR) LEN(3) VALUE('*+ ') 

IF COND(%TRIM(&NAME &TCHAR) *EQ '12345') + 

   THEN(SNDPGMMSG ('EQUAL!'))

 

除了空格,还可以指定任何你想删掉的位于字符串首尾处的字符。上面的例子,我们会收到 'EQUAL!' 的消息。你可能也注意到了,就是 %TRIM 能够用在任何可以指定字符表达式的地方。有点意思了,是吗?还不止这些,再看看下面的例子。

DCL VAR(&NUM) TYPE(*CHAR) LEN(10) VALUE('  **1.23**') 

DCL VAR(&DEC) TYPE(*DEC) LEN(3 2)

/* &DEC will have the value 1.23 */

CHGVAR VAR(&DEC) VALUE(%TRIM(&NUM '* '))

 

%TRIM 后的结果,还可以转换成数字类型,是不是比以前省事多了?设想这样的场景,我们需要把每一笔销售额累加,得到总销售额。可是销售额的字段里除了有数字,还有‘$’之类的编辑字符。以前我们需要写一段小程序,去掉数字之外的字符,再把它转换成数字类型,再做累加。现在有了 %TRIM,只需要像上面例子那样,一行 CHGVAR 命令就完成了,有些心动的感觉了吗?

 

也许有时你只想处理掉字符串首部的某些字符,有时你只想处理掉字符串尾部的某些字符,还有 %TRIML 和 %TRIMR 可以选择,心满意足了吗?

 

接下来看看另外一组函数:%CHECK,%CHECKR,%SCAN。

PGM PARM(&SN) 

DCL VAR(&SN) TYPE(*CHAR) LEN(10) 

IF COND(%CHECK('0123456789' &SN) *NE 0) + 

   THEN(SNDPGMMSG ('INVALID CHARACTER FOUND!'))

 

上面 %CHECK 函数返回的是第一个不是 '0123456789' 的字符在 &SN 中的位置。如果变量 &SN 里含有 '0123456789'  以外的字符,那么 %CHECK 的结果就不为 0,我们会收到 'INVALID CHARACTER FOUND!' 的消息。我们遇到的很多数据,都是由特定的一组字符组成的,比如电话号码里只能有 ' –()0123456789',时间里只能有 ':0123456789',日期里只能有 '-/.0123456789',使用 %CHECK 函数,可以很容易检查数据里是否有非法字符。

 

如果你想知道字符串里所有的非法字符,可以参考下面这个例子。

DCL VAR(&TELNUM) TYPE(*CHAR) LEN(20)

DCL VAR(&POS) TYPE(*INT)

 

CHGVAR VAR(&POS) VALUE(%CHECK(' -()0123456789' &TELNUM))

 

DOWHILE COND(&POS *NE 0)

SNDPGMMSG MSG('INVALID CHARACTER' *BCAT +

             %SST(&TELNUM &POS 1) *BCAT 'FOUND.')

  IF COND(&POS *EQ 20) THEN(LEAVE)

  CHGVAR VAR(&POS) VALUE(&POS + 1)

  CHGVAR VAR(&POS) +

             VALUE(%CHECK(' -()0123456789' &TELNUM &POS))

ENDDO

 

如果你想知道一个字符串在 padding 之前的长度,可以用 %CHECKR 函数。

DCL VAR(&LEN) TYPE(*INT)

DCL VAR(&STRING) TYPE(*CHAR) LEN(20) VALUE('JOHN SMITH*****')

DCL VAR(&PADCHARS) TYPE(*CHAR) LEN(2) VALUE(' *')

CHGVAR VAR(&LEN) VALUE(%CHECKR(&PADCHARS &STRING))

/* &LEN will have the value 10 */

 

最后一个出场的是 %SCAN。我们经常需要知道一个字符串里是否包含另一个字符串,这是可以用 %SCAN。

DCL VAR(&POS) TYPE(*UINT) LEN(2)

CHGVAR VAR(&POS) VALUE(%SCAN('Escape' *LDA))

 

上面的 %SCAN 返回的是第一个 'Escape' 在 local data area 里的位置。如果 &POS 不为 0,说明 local data area 里含有 Escape 消息。当然,也可以给 %SCAN 指定第三个参数,说明从字符串的什么位置开始查找。

 

%CHECK,%CHECKR 和 %SCAN 能够用在任何可以指定算数表达式的地方。

 

看了这些新增的 CL 内建函数,是不是迫不及待的想亲自实践一下,只要在 IBM i 7.1 上安装了 PTF SI49061,就能够拥有它们了! 另外,也可以指定 CRTCLPGM,CRTCLMOD,和 CRTBNDCL 的 TGTRLS 参数,把 7.1 上编好的程序,拿到 6.1 或者 5.4 上运行。

 

更多的语法说明,请参考:

https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/IBM%20i%20Technology%20Updates/page/New%20built-in%20functions%20have%20been%20added%20to%20both%20OPM%20CL%20and%20ILE%20CL%20that%20make%20string%20handling%20easier%20and%20faster

 

作者:

刘珍  liuzliuz@cn.ibm.com  IBM中国系统与技术中心  负责Control Language (CL) 编译器的开发和维护, 以及CL Command相关的维护工作。

 

[{"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG60","label":"IBM i"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB57","label":"Power"}}]

UID

ibm11144852