%SCAN(扫描字符)

%SCAN(search argument : source string {: start position {: length {: *NATURAL | *STDCHARSIZE}}})

%SCAN 返回搜索自变量在源字符串中的第一个位置,如果找不到,那么返回 0。

起始位置和长度指定要搜索的源字符串的子串。 开始位置缺省为 1 ,长度缺省为源字符串的其余部分。 结果始终是源字符串中的位置,即使指定了起始位置也是如此。

第一个和第二个参数必须是字符、图形或 UCS-2 类型。 如果第一个参数的类型或 CCSID 与第二个参数不相同,则第一个参数将转换为第二个参数的类型和 CCSID。

如果指定了第三个和第四个参数,那么这些参数必须是不带小数位的数字。

第三个,第四个或第五个参数可以是 *NATURAL 或 *STDCHARSIZE ,以覆盖语句的当前 CHARCOUNT 方式。 如果指定了此参数,那么它必须是最后一个参数。
  • 指定 *NATURAL 以指示 %SCAN 以 CHARCOUNT NATURAL 方式运行。 开始位置,长度和返回值以字符而不是字节或双字节为单位进行测量。 例如,如果源字符串是值为 "ábç12" 的 UTF-8 字符串,那么 3 的起始位置表示 "ç" ,因为它是第三个字符。
  • 指定 *STDCHARSIZE 以指示 %SCAN 在 CHARCOUNT STDCHARSIZE 方式下运行。 在上一个示例中,使用 CHARCOUNT STDCHARSIZE 方式时, 3 的起始位置引用 "b" ,因为它是第三个字节。 字符 "á" 和 "ç" 是 2 字节字符。
请参阅 按每个字符的自然大小处理字符串数据字符数据类型
注: 由于 /CHARCOUNT 编译器伪指令或 CHARCOUNT Control 关键字, %SCAN 也可以在 CHARCOUNT NATURAL 方式下运行。

当任何参数的长度是可变的时,将根据当前长度而不是最大长度来检查其他参数的值。

返回值的类型为数字。 此内置函数可以在数字表达式有效的任何位置使用。

如果搜索参数包含尾部空格,那么扫描将包含这些尾部空格。 例如,如果 "b" 表示空白,那么 %SCAN ("12b": "12312b") 将返回 4。 如果不应在扫描中考虑尾部空格,请在搜索自变量上使用 %TRIMR。 例如 %SCAN (%TRIMR ('12b'): '12312b') 将返回 1。

有关更多信息,请参阅 字符串操作内置函数

注: 与 SCAN 操作码不同, %SCAN 无法返回包含所有出现的搜索字符串的数组,并且无法使用 %FOUND 内置函数来测试其结果。

%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 个空格。 但是,posTrimposVar 的值都是 1,因为 %TRIMR 和 srchFldVar 扫描都使用 3 字节的搜索参数 "Dr."、 没有尾部空格。

有关比较 %SCAN 和 %SCANR 的示例,请参阅 将 %SCAN 和 %SCANR 一起使用的示例