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 上运行。
更多的语法说明,请参考:
作者:
刘珍 liuzliuz@cn.ibm.com IBM中国系统与技术中心 负责Control Language (CL) 编译器的开发和维护, 以及CL Command相关的维护工作。
UID
ibm11144852