%SCAN(扫描字符)
%SCAN(search argument : source string {: start position {: length {: *NATURAL | *STDCHARSIZE}}})
%SCAN 返回搜索自变量在源字符串中的第一个位置,如果找不到,那么返回 0。
起始位置和长度指定要搜索的源字符串的子串。 开始位置缺省为 1 ,长度缺省为源字符串的其余部分。 结果始终是源字符串中的位置,即使指定了起始位置也是如此。
第一个和第二个参数必须是字符、图形或 UCS-2 类型。 如果第一个参数的类型或 CCSID 与第二个参数不相同,则第一个参数将转换为第二个参数的类型和 CCSID。
如果指定了第三个和第四个参数,那么这些参数必须是不带小数位的数字。
- 指定 *NATURAL 以指示 %SCAN 以 CHARCOUNT NATURAL 方式运行。 开始位置,长度和返回值以字符而不是字节或双字节为单位进行测量。 例如,如果源字符串是值为 "ábç12" 的 UTF-8 字符串,那么 3 的起始位置表示 "ç" ,因为它是第三个字符。
- 指定 *STDCHARSIZE 以指示 %SCAN 在 CHARCOUNT STDCHARSIZE 方式下运行。 在上一个示例中,使用 CHARCOUNT STDCHARSIZE 方式时, 3 的起始位置引用 "b" ,因为它是第三个字节。 字符 "á" 和 "ç" 是 2 字节字符。
当任何参数的长度是可变的时,将根据当前长度而不是最大长度来检查其他参数的值。
返回值的类型为数字。 此内置函数可以在数字表达式有效的任何位置使用。
如果搜索参数包含尾部空格,那么扫描将包含这些尾部空格。 例如,如果 "b" 表示空白,那么 %SCAN ("12b": "12312b") 将返回 4。 如果不应在扫描中考虑尾部空格,请在搜索自变量上使用 %TRIMR。 例如 %SCAN (%TRIMR ('12b'): '12312b') 将返回 1。
%SCAN 示例
*..1....+....2....+....3....+....4....+....5....+....6....+....7...+....
D*Name++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++
D source S 15A inz ('Dr. Doolittle')
D pos S 5U 0
D posTrim S 5U 0
D posVar S 5U 0
D srchFld S 10A
D srchFldVar S 10A varying
pos = %scan ('oo' : source);
上次分配后, pos 的值为 6 ,因为 "oo" 从 "Dr." 中的位置 6 开始 多利特尔
pos = %scan ('D' : source : 2);
在先前分配后, pos 的值为 5 ,因为从位置 2 开始找到的第一个 "D" 位于位置 5。
pos = %scan ('D' : source : 2 : 3);
在上次分配后, pos 的值为 0 ,因为在位置 2 处找不到长度为 3 的 "D"。
pos = %scan ('D' : source : 2 : 4);
在上次分配后, pos 的值为 5 ,因为在搜索从位置 2 开始时找到长度为 4 的 "D"。
pos = %scan ('abc' : source);
在上次分配后, pos 的值为 0 ,因为在 "Dr." 中找不到 "abc" 多利特尔
pos = %scan ('Dr.' : source : 2);
在上次分配后, pos 的值为 0 ,因为 "Dr." 在 "博士" 中找不到 Doolittle ' ,如果搜索从位置 2 开始。
srchFld = 'Dr.';
srchFldVar = 'Dr.';
pos = %scan (srchFld : source);
posTrim = %scan (%trimr(srchFld) : source);
posVar = %scan (srchFldVar : source);
在先前语句之后, pos 的值为 0 ,因为 srchFld 是一个 10 字节的字段,所以搜索参数为 "Dr." 接着是 7 个空格。 但是,posTrim 和 posVar 的值都是 1,因为 %TRIMR 和 srchFldVar 扫描都使用 3 字节的搜索参数 "Dr."、 没有尾部空格。
有关比较 %SCAN 和 %SCANR 的示例,请参阅 将 %SCAN 和 %SCANR 一起使用的示例。