ABAP正则表达式 特殊字符处理
REPLACE ALL OCCURRENCES OF REGEX '[[:space:]]' IN <fs_purhdinfo>-cell_value WITH ''."可去掉空格或回车键
REPLACE ALL OCCURRENCES OF ':' IN <fs_purhdinfo>-cell_value WITH ''."可去掉空格或回车键
REPLACE ALL OCCURRENCES OF REGEX '[[:cntrl:]]' IN <fs_purhdinfo>-cell_value WITH ''.
REPLACE ALL OCCURRENCES OF REGEX '[[:space:]]' IN <fs_purhdinfo>-cell_formula WITH ''."可去掉空格或回车键
REPLACE ALL OCCURRENCES OF ':' IN <fs_purhdinfo>-cell_formula WITH ''."可去掉空格或回车键
REPLACE ALL OCCURRENCES OF REGEX '[[:cntrl:]]' IN <fs_purhdinfo>-cell_formula WITH ''.
正则表达式:
是否包含字母数字类,比如域账号判断
IF cl_abap_matcher=>matches( pattern = '^[a-z0-9A-Z_]+$' text = lv_ key ).
IF cl_abap_matcher=>matches( pattern = '[a-z|A-Z]*-?[a-z|A-Z]*[0-9?]*' text = lv_key ).
判断字符串中是否包含汉字
*" REFERENCE(IV_INPUT) TYPE STRING
*" REFERENCE(EV_OUT) TYPE C
DATA: alpha_num(120) TYPE c.
alpha_num = ' abcdefghijklopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,./;''[]\-=`<>?:"{}|_+~!@#$%^&*()'.
IF NOT IV_input CO alpha_num.
EV_OUT = ABAP_TRUE. "'含有汉字'.
ELSE.
EV_OUT = SPACE. "不含汉字
ENDIF.
ENDFUNCTION.
特殊字符:
REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN ls_z023-kxytx WITH space. "TAB符
REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf IN ls_z023-kxytx WITH space. "回车换行
REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline IN ls_z023-kxytx WITH space. "换行
CONDENSE ls_z023-kxytx NO-GAPS.
正则表达式
ABAP中可以使用regex的地方
除了下面两个语句可以使用regex外:
- FIND
- REPLACE
下面主函数的参数也可以使用regex:
- count()
- contains()
- find()
- match()
- matches()
- replace()
- substring()
另外,还有两个类也可以使用regex:
- CL_ABAP_REGEX
- CL_ABAP_MATCHER
正则式语法规则
下面都是针对单个字符匹配的:
Special character | Meaning |
. | 任何单个字符 |
\C | 与.意义一样:可匹配任何单个字符 |
\d | 任何单个数字字符 |
\D | 任何单个非数字字符 |
\l | 任何单个小写字母字符lowercase letter |
\L | 任何单个非小写字母字符lowercase letter |
\s | 任何一个空白字符a blank character |
\S | 任何一个非空白字符a blank character |
\u | 任何单个大写字母字符uppercase letter |
\U | 任何单个非大写字母字符uppercase letter |
\w | 任何单个字母数字字符,包括下划线 _ any alphanumeric character including _ |
\W | 任何单个非字母数字字符,并排除下划线 _ non-alphanumeric character except for _ |
[ ] | 任何单个字符集a value set for single characters |
[^ ] | 字符集之外的其他任何单个字符 如果^不在[…]里最前面,则^表示只是一个普通的^字符,而不是取反的意思,如[A^B] 中的^ 会匹配普通的字符^ |
[ - ] | 范围字符集 a range in a value set for single characters 如果-不在[…]两个字符之间(但a-z-Z这种不算),则-表示只是一个普通的-字符,而不是范围意思,如[A-Za-z0-9-]中的最后-可以匹配到- |
[[:alnum:]] | [:alpha:] 与 [:digit:]并集(字母+数字alphanumeric characters) |
[[:alpha:]] | 字母字符集 |
[[:blank:]] | 空白字符集 blank characters and horizontal tabulators(制表) in a value set |
[[:cntrl:]] | 控制字符集all control characters in a value set |
[[:digit:]] | 与 \d 等效 |
[[:graph:]] | 除开空白字符与垂直制表符外的所有可显示字符 Description of all characters in a value set that can be displayed apart from blank characters and horizontal tabulators |
[[:lower:]] | 所有小写字母字符集 lowercase letters in a value set |
[[:print:]] | [:graph:] 与 [:blank:],可显示字符集,all characters in a value set that can be displayed |
[[:punct:]] | 所有的标点字符集all punctuation characters in a value set |
[[:space:]] | 空白字符+制表符+回车换行符 blank characters, tabulators, and carriage feeds in a value set |
[[:unicode:]] | 所有大于255的Unicode字符 Unicode characters in a value set with a code larger than 255 |
[[:upper:]] | 大写字母字符集 uppercase letters in a value set |
[[:word:]] | 字母数字+下划线 alphanumeric characters in a value set, including _ |
[[:xdigit:]] | 十六进制数字 hexadecimal digits in a value set |
\a \f \n \r \t \v | 各种控制字符 Various platform-specific control characters |
[..] | 为以后增强所保留,目前不支持 Reserved for later enhancements |
[==] | 为以后增强所保留,目前不支持 Reserved for later enhancements |
Special character | Meaning | |||||||||||||||
{n} | 出现n次 | |||||||||||||||
{n,m} | 出现n到m次 | |||||||||||||||
{n,m}? | 为以后增强所保留,目前不支持 Reserved for later enhancements {n,m}?, *?,+?属于非贪婪,但目前ABAP中不支持非贪婪 | |||||||||||||||
? | 0次或1次 | |||||||||||||||
* | 0次或多次 | |||||||||||||||
*? | 为以后增强所保留,目前不支持 Reserved for later enhancements | |||||||||||||||
+ | 1次或多次 | |||||||||||||||
+? | 为以后增强所保留,目前不支持 Reserved for later enhancements | |||||||||||||||
| | 或者 Linking of two alternative expressions r|st = r|(?:st)不等于(?:r|s)t r|s+ = r|(?:s+)不等于(?:r|s)+
| |||||||||||||||
( ) | 捕获组(分组) | |||||||||||||||
(?: ) | 非捕获组(分组,但不捕获) | |||||||||||||||
\1, \2,\3... | 正则表达式中的分组引用 | |||||||||||||||
\Q ... \E | 在\Q ... \E之间的所有字符都会看作是普通的字符:
Definition of a string of literal characters | |||||||||||||||
(? ... ) | 为以后增强所保留,目前不支持 Reserved for later enhancements (? ... ) 已被保留,除了(?:...)、(?=...)、(?!...)三种目前支持之外,其他所以的(? ... )这种形式都会抛异常CX_SY_INVALID_REGEX |
Special character | Meaning |
^ | 字符串的开头或行的开头 Anchor character for the start of a line |
\A | 字符串的开头 Anchor character for the start of a character string |
$ | 字符串结尾、字符串结尾的 \n 之前或行的结尾(不会匹配到\n,如果最末有\n,只会匹配到它之前) Anchor character for the end of a line |
\z | 字符串的结尾 Anchor character for the end of a character string |
\Z | 字符串的结尾或字符串结尾的 \n 之前 Like \z, whereby line breaks at the end of the character string are ignored |
\< | 单词的开头,即匹配单词边界,不匹配任何字符 Start of a word |
\> | 单词的结尾,即匹配单词边界,不匹配任何字符 End of a word |
\b | 单词的开头或结尾,即匹配单词边界,不匹配任何字符 Start or end of a word |
\B | 与上面的\b相反,即非单词边界 Space between characters within a word |
(?= ) (?! ) | 正向搜索(正) Preview condition |
正向搜索(负) Negated preview condition | |
(?> ) | Cut operator不知道这个有什么用???? |
Special character | Meaning |
0, 0,& | 整个匹配 Placeholder for the whole found location |
1, 1,2, $3... | 子匹配分组(捕获组)引用 Placeholder for the register of subgroups |
$` | 匹配到的子串之前的所有字符串 Placeholder for the text before the found location |
$' | 匹配到的子串之后的所有字符串 Placeholder for the text after the found location |
(?=…)、(?!...)
注:SAP反向搜索(?<=...)、(?<!...)目前不支持,只支持正向搜索(?=...)、(?!...),但Java都支持
DATA text TYPE string.
DATA result_tab TYPE match_result_tab WITH HEADER LINE.
text = `Shalalala!`.
FIND ALL OCCURRENCES OF REGEX '(?:la)(?=!)'
IN text RESULTS result_tab[].
LOOP AT result_tab .
WRITE: / result_tab-offset, result_tab-length.
ENDLOOP.
7 2
\A 、\z、\Z与^ 、$区别
^ 指定的匹配必须出现在字符串的开头或行的开头(即 \n后面第一个字符)。
$ 指定的匹配必须出现在以下位置:字符串结尾、字符串结尾的 \n 之前或行的结尾(不会匹配到\n,如果最末有\n,只会匹配到它之前)。
\A 指定匹配必须出现在字符串的开头(忽略 Multiline 选项)。
\z 指定匹配必须出现在字符串的结尾(忽略 Multiline 选项)。
\Z 指定匹配必须出现在字符串的结尾或字符串结尾的 \n 之前(忽略 Multiline 选项)。
\A 、\z、\Z与^ 、$不同的是,只搜索第一行
DATA text TYPE string.
"在ABAP中如果要在字符中插入回车换行字符时,需要使用 ||,而不是使用单引号引起来
text = |zzz\nabc\n|.
IF contains( val = text regex = '^abc' ) .
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
"如果是将 ^ 换成 \A 时,则结果不会匹配
IF contains( val = text regex = '\Aabc' ).
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
IF contains( val = text regex = 'z$' ).
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
IF contains( val = text regex = 'c$' ).
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
IF contains( val = text regex = 'z\z' ).
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
IF contains( val = text regex = 'z\Z' ).
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
IF contains( val = text regex = 'c\z' ).
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
IF contains( val = text regex = 'c\Z' ).
WRITE:/ 'Yes'.
ELSE.
WRITE:/ 'No'.
ENDIF.
Yes
No
Yes
Yes
No
No
No
Yes
$0…、$&、$`、$′
替换串里可以出现$、&、`、 ′
$0、$&:表示的是整个正则式所匹配到的子串,即好比整个正则式使用 ( ) 括起来一样,但不使用 ( ) 括起来整个regex所匹配的子串还是$0,即$0与整个regex是否使用了 ( ) 括起来没有关系,但是,如果使用了( )将整个regex括起来了,则对后面的$1…是有影响的,整个regex此时会是$1,这与Java是不一样的
DATA text TYPE string.
text = `Yeah!+`.
REPLACE REGEX `((Y)e(a)h(!))` IN text WITH `-&-&-0- 1− 1−2- 3− 3−4-`.
WRITE:/ text.
text = `Yeah!`.
REPLACE REGEX `\w+` IN text WITH `-&-&-0-`.
WRITE:/ text.
-Yeah!-Yeah!-Yeah!-Y-a-!-+
-Yeah-Yeah-!
$`表示所匹配到的子串之前的所有字符串,如果多次相同匹配,则所取到的是未经替换过的前面部分源串:
DATA text TYPE string.
text = `again and abc and def`.
REPLACE ALL OCCURRENCES OF REGEX 'and' IN text WITH '($0 $`)'.
WRITE:/ text.
again (and again ) abc (and again and abc ) def
$'表示所匹配到的子串之后的所有字符串:
DATA: text TYPE string.
text = `again and again abc`.
REPLACE ALL OCCURRENCES OF REGEX `again ` IN text WITH `($' $0)`.
WRITE:/ text.
(and again abc again )and (abc again )abc
\1、\2、\3…
在分组正则式里,可以使用\1, \2, \3…方式引用regex分组,与$分组不一新的是,只要用括号括起来的最左且最外的Regex为\1,而不是\0
Pattern | Text | Match |
(["']).+\1 | "Hello" | X |
(["']).+\1 | "Hello' | - |
(["']).+\1 | 'Hello' | X |
As of Release 7.00, ABAP supports POSIX-style regular expressions
正则中的特殊字符:. * + ? | ^ $ ( ) [ ] { } \,可以使用\将这些特殊字符转义普通的字符
FIND
FIND [{FIRST OCCURRENCE}|{ALL OCCURRENCES} OF]
{[SUBSTRING] sub_string} | {REGEX regex}
IN [SECTION [OFFSET off] [LENGTH len] OF] dobj
[IN {BYTE|CHARACTER} MODE]
[{RESPECTING|IGNORING} CASE]
[MATCH COUNT mcnt]
{ {[MATCH OFFSET moff][MATCH LENGTH mlen]}
| [RESULTS result_tab|result_wa] }
[SUBMATCHES s1 s2 ...].
0 | 至少找到一次 |
4 | 未找到 |
[{FIRST OCCURRENCE}|{ALL OCCURRENCES} OF]
如果未指定或者指定为FIRST OCCURRENCE,则只搜索第一次出现的。
{[SUBSTRING] sub_string} | {REGEX regex}
FIRST OCCURRENCE或者未指定时,如果sub_string是空String类型的字符串或者内容为空格的固定长度类型(c, d, n, or t)的字符串时,sub_string将会被看作是empty 类型的字符串,并且查找的位置将定位到dobj的首字符前。但如果sub_string是空字符串(包括字符类型字符串类型),使用ALL OCCURRENCES选项,则会抛异常。
DATA: textTYPE string VALUE`Hey hey`,
moff TYPEi,
mlen TYPEi,
mcnt TYPEi.
FINDFIRST OCCURRENCE OF SUBSTRING ''INtext
MATCH OFFSET moff
MATCH LENGTH mlen
MATCH COUNT mcnt.
WRITE: moff, mlen,mcnt.
FINDFIRST OCCURRENCE OF SUBSTRING ' 'INtext
MATCH OFFSET moff
MATCH LENGTH mlen
MATCH COUNT mcnt.
WRITE: moff, mlen,mcnt.
FINDFIRST OCCURRENCE OF SUBSTRING ``INtext
MATCH OFFSET moff
MATCH LENGTH mlen
MATCH COUNT mcnt.
WRITE: moff, mlen,mcnt.
FINDFIRST OCCURRENCE OF SUBSTRING ` `INtext
MATCH OFFSET moff
MATCH LENGTH mlen
MATCH COUNT mcnt.
WRITE: moff, mlen,mcnt.
"以下三个语句运行时会抛异常
"FIND ALL OCCURRENCES OF SUBSTRING `` IN text MATCH OFFSET moff.
"FIND ALL OCCURRENCES OF SUBSTRING '' IN text MATCH OFFSET moff.
"FIND ALL OCCURRENCES OF SUBSTRING ' ' IN text MATCH OFFSET moff.
0 0 1 0 0 1 0 0 1 3 1 1
sub_string为固定长度类型的字符串时,尾部空格将被忽略,如果不想忽略尾部空格,则使用String类型的sub_string。
regex不允许为空的String类型的字符串或者内容只有空格的固定长度类型(c, d, n, or t)的字符串,以下编译时会出错:
DATA: textTYPE string VALUE`Hey hey`,
moff TYPEi.
FINDFIRST OCCURRENCE OF REGEX ''INtext
MATCH OFFSET moff.
FINDFIRST OCCURRENCE OF REGEX ``INtext
MATCH OFFSET moff.
IN [SECTION [OFFSET off] [LENGTH len] OF] dobj
如果未加上SECTION选项,将对整个dobj字符串进行匹配操作。如果指定了SECTION选项,则OFFSET与LENGTH必须选择一个。如果指定如果指定了OFFSET,但未指定LENGTH时,查找的区域从OFFSET到dobj的最后;如果指定了LENGTH,但未指定OFFSET时,OFFSET将隐含为0。OFFSET与LENGTH需要大于或等于0,通过OFFSET与LENGTH定位到的子字符串段必须要位于dobj里。
[{RESPECTING|IGNORING} CASE]
是否区分大小写,默认区分
[MATCH COUNT mcnt]
成功查找的次数,如果使用了FIRST OCCURRENCE选项,则通常是1
[MATCH OFFSET moff]
最后一次匹配的子串(是指整体正则分组,即Java中的第0组)起始位置。如果没有查找到,则为以前的值。
注:FIND不影响sy-fdpos系统字段
[MATCH LENGTH mlen]
最后一次匹配到的子串(是指整体正则分组,即Java中的第0组)的长度(注:与REPLACE不同的是,REPLACE指的是替换的长度)。
[RESULTS result_tab|result_wa]
result_tab接收所有匹配结果,而result_wa只能接收最后一次匹配结果
FIRST OCCURRENCE 一般与result_wa 一起使用,如果与result_tab结合,则最多只有一条结果。
如果查找不成功,则result_tab为initial,result_wa为以前的值。
result_wa适合于与FIRST OCCURRENCE结合使用,而result_tab适合于与ALL OCCURRENCES结合使用。
result_tab必须是MATCH_RESULT_TAB类型的内表
result_wa为MATCH_RESULT类型的结构
- OFFSET 匹配到的子字符串位置dobj的位置
- LENGTH 匹配到的子字符串长度
- SUBMATCHES 类型为SUBMATCH_RESULT_TAB 的内表,行类型为SUBMATCH_RESULT。该类型存储了所有子分组匹配(只要是括号括起来的,就是一个子分组,那怕括起来的是整个正则式——如果整个正则式不括起来,则不会像Java那样自动成为一个子分组)
- LINE 仅在使用FIND IN TABLE才有意思
[SUBMATCHES s1 s2 ...]
SUBMATCHES 选项只在REGEX regex情况下使用,并且只会接收使用括号进行分组的子组。
如果变量s1 s2 ...比分组的数量多,则多余的变量被initial;如果变量s1 s2 ...比分组的数量少,则多余的分组将被忽略。
DATA: text TYPE string,
moff TYPE i,
mlen TYPE i,
mcnt TYPE i,
s1 TYPE string,
s2 TYPE string,
s3 TYPE string,
s4 TYPE string.
text = `Hey hey, my my, Rock Hey hey, my my,`.
FIND ALL OCCURRENCES OF REGEX `(\w+)\W+\1\W+(\w+)\W+\2`
IN text
IGNORING CASE
"以下两个变量存储的是第二次匹配到的子串(整体正则式)相关信息
MATCH OFFSET moff
MATCH LENGTH mlen
"会发生2次匹配
MATCH COUNT mcnt
"会发生两次匹配,第一次为:Hey hey, my my,第二次为:Hey hey, my my
"注,虽然这里使用使用了4个变量接收分组,但正则式中每次只会有两个
"分组,所以接收每次匹配结果只需要2个变量,s3与s4不会用到,而不是第二次
"时将匹配到的结果存放到s3与s4中
SUBMATCHES s1 s2 s3 s4.
WRITE: / moff, / mlen,/ s1, / s2, / s3,/ s4.
21
14
2
Hey
my
精确查找(一次性解析)
{[SUBSTRING] sub_string} | {REGEX regex}:为FIND的两种使用方式。第一种表式在dobj串中精确查找子字符串sub_string(SUBSTRING可以省略),此种方式sub_string不支持正则试,即使使用也会当作普通字符串。如:
DATA: result_tab TYPE match_result_tab.
FIELD-SYMBOLS <match> LIKE LINE OF result_tab.
FIND ALL OCCURRENCES OF `now` IN`Everybody knows this is nowhere`
RESULTS result_tab.
LOOP AT result_tab ASSIGNING <match>.
WRITE: / <match>-offset, <match>-length.
ENDLOOP.
11 3
24 3
精确查找(循环查找)
上面程序可以使用以下循环方式来代替(这种方式适合以7.0以前版本),而不是将结果一次性存入到match_result_tab类型的内表中:
DATA: off TYPE i,
moff TYPE i,
mlen TYPE i.
off = 0.
WHILE sy-subrc = 0.
FIND `now` IN SECTION OFFSET off OF
`Everybody knows this is nowhere`
MATCH OFFSET moff
MATCH LENGTH mlen.
IF sy-subrc = 0.
WRITE: / moff,mlen.
off = moff + mlen.
ENDIF.
ENDWHILE.
11 3
24 3
使用正则式
DATA: moff TYPE i,
mlen TYPE i,
s1 TYPE string,
s2 TYPE string,
s3 TYPE string,
s4 TYPE string.
"(a).|([ab]+)等效于 ((a).)|([ab]+)。正则式是按最贪婪(最多或者最长匹配)
"方式来匹配,所以 (a).|([ab]+) 会选择后者。另外,分组数只与括号有关,并
"按括号从左到右,从外到里顺次为第一组,第二组,第...,与 | 没有关系,即分
"组数不会随着 | 的正则式选择不同而改变
FIND REGEX '(((a).)|([ab]+))' IN 'oooababboo'
MATCH OFFSET moff
MATCH LENGTH mlen
SUBMATCHES s1 s2 s3 s4.
WRITE: / 's1=',s1,'s2=',s2,'s3=',s3,'s4=',s4, / moff,mlen.
s1= ababb s2= s3= s4= ababb
3 5
DATA: result_tab TYPE match_result_tab.
FIND ALL OCCURRENCES OF REGEX `((ab)|(ba))`
IN 'abba'
RESULTS result_tab.
因为正则表达式中的子分组使用或连接的,每次匹配过程中,虽然有3个子分组,但每次只有其中某两个才能真正匹配上。
DATA: moff TYPE i,
mlen TYPE i,
s1 TYPE string,
s2 TYPE string.
FIND REGEX `((\w+)\W+\2\W+(\w+)\W+\3)`
IN `Hey hey, my my, Rock and roll can never die`
IGNORING CASE
MATCH OFFSET moff
MATCH LENGTH mlen
SUBMATCHES s1 s2."根据从外到内,从左到右的括号顺序依次存储到s1 s2…中,注:取出部分一定要使用括号括起来,即使是取出匹配整个正则式的部分也得括起来,这与Java不同,正则式外层默认情况下是没有括号括起来,但Java默认情况下整体就是一个分组,且是第0分组,但ABAP是从1开始编号子分组的(指使用括号括起来的才算,如果整个正则式未使用括号,则不会算做一个子分组)
WRITE: / s1, / s2,/ moff ,/ mlen.
Hey hey, my my
Hey
0
14
匹配所有分组(RESULTS result_tab)公共函数
START-OF-SELECTION.
DATA: result TYPE STANDARD TABLE OF string WITH HEADER LINE .
"与Java不同,只要是括号括起来的都称为子匹配(即整体也得用括号括起来了),不管括号嵌套多少层,统
"称为子匹配,且匹配到的所有子串都会存储到MATCH_RESULT-SUBMATCHES中,
"即使最外层的括号匹配子串也会存储到SUBMATCHES内表中。括号解析的顺序为:
"从外到内,从左到右的优先级顺序来解析匹配结构。Java中的group(0)存储的
"是整体匹配串,即使整体未(或使用)使用括号括起来
PERFORM get_match TABLES result
USING '20110921' '^(((\d{2})(\d{2}))(\d{2})(\d{2}))$'.
LOOP AT result .
WRITE: / result.
ENDLOOP.
FORM get_match TABLES p_result"默认会带表头
USING p_str
p_reg.
DATA: result_tab TYPE match_result_tab WITH HEADER LINE.
DATA: subresult_tab TYPE submatch_result_tab WITH HEADER LINE.
"注意:带表头时 result_tab 后面一定要带上中括号,否则激活时出现奇怪的问题
FIND ALL OCCURRENCES OF REGEX p_reg IN p_str RESULTS result_tab[].
LOOP AT result_tab .
p_result = p_str+result_tab-offset(result_tab-length).
APPEND p_result.
subresult_tab[] = result_tab-submatches.
LOOP AT subresult_tab.
p_result = p_str+subresult_tab-offset(subresult_tab-length).
APPEND p_result.
ENDLOOP.
ENDLOOP.
ENDFORM.
20110921
20110921
2011
20
11
09
21
REPLACE
REPLACE [{FIRST OCCURRENCE}|{ALL OCCURRENCES} OF]
{[SUBSTRING] sub_string} | {REGEX regex}
IN [SECTION [OFFSET off] [LENGTH len] OF] dobj
WITH new
[IN {BYTE|CHARACTER} MODE]
[{RESPECTING|IGNORING} CASE]
[REPLACEMENT COUNT rcnt]
{ {[REPLACEMENT OFFSET roff]
[REPLACEMENT LENGTH rlen]}
| [RESULTS result_tab|result_wa] }.
语法与FIND相似。
如果new尾部空格需要保留,则要使用String类型的new,其他固定长度类型的new字符,会忽略掉尾部空格。
{FIRST OCCURRENCE}|{ALL OCCURRENCES} OF
FIRST OCCURRENCE或者未指定时,只替换第一次匹配的;ALL OCCURRENCES则替换所有子匹配串
{[SUBSTRING] sub_string} | {REGEX regex}
[SUBSTRING] sub_string:以固定的字符串为匹配模式进行搜索并替换,与前面替换指定的字符串的REPLACE是一样的。
FIRST OCCURRENCE或者未指定时,如果sub_string是空String类型的字符串或者内容为空格的固定长度类型(c, d, n, or t)的字符串时,sub_string将会被看作是empty 类型的字符串,并且查找替换的位置将定位到dobj的首字符前,并且将new插入到dobj最前面。但如果sub_string是空字符串(包括字符类型字符串类型),使用ALL OCCURRENCES选项,则会抛异常。
sub_string为固定长度类型的字符串时,尾部空格将被忽略(这与老式的REPLACE规则不同),如果不想忽略尾部空格,则使用String类型的sub_string。
REGEX regex:使用正则表达式进行匹配替换。
regex不允许为空String类型的字符串或者内容只有空格的固定长度类型(c, d, n, or t)的字符串。
DATA text TYPE string VALUE '-uu-'.
"U*表示0个或多个U,当为0个时,字符间的空隙就相匹配"U*与UU相匹配,替换的结果为第三个 x
REPLACE ALL OCCURRENCES OF REGEX 'u*' IN text WITH 'x'.
WRITE:/ text.
x-xx-x
IN [SECTION [OFFSET off] [LENGTH len] OF] dobj
如果未加上SECTION选项,将对整个dobj字符串进行匹配替换操作。如果指定了SECTION选项,则OFFSET与LENGTH必须选择一个。如果指定如果指定了OFFSET,但未指定LENGTH时,替换的区域从OFFSET到dobj的最后;如果指定了LENGTH,但未指定OFFSET时,OFFSET将隐含为0。OFFSET与LENGTH需要大于或等于0,通过OFFSET与LENGTH定位到的子字符串段必须要位于dobj里。该选项与前面替换某个区间上的字符串的REPLACE是一样的,与FIND也相同。
[{RESPECTING|IGNORING} CASE]
区分与忽略大小写,对在 IN CHARACTER MODE 模式下使用,默认区别大小写
[REPLACEMENT COUNT rcnt]
成功替换的次数,如果没有发生替换,则为0
注:如果dobj为固定长度类型的字符串时,则发生替换的次数 rcnt 可能少于本应该查找到的次数。
[REPLACEMENT OFFSET roff]
最后一次替换发生在 dobj 中的起始位置,如果没有发生替换,则保留的是以前的值。
[REPLACEMENT LENGTH rlen]
最的一次dobj替换完成后替换结果段的长度(注:不是指查到的sub_string长度的,而是指定成功替换后被插入部分的长度,这与FIND函数是不一样的,这里一般等于 new 的长度),如果没有发生替换,则保留的是以前的值。
注:如果dobj为固定长度类型的字符串时,rlen可能小于 new 的长度。
关于rcnt变少、rlen变小的示例:
DATA: text(9) VALUE 'aaacccccc'.
DATA: roff TYPE i, rlen TYPE i,rcnt TYPE i.
REPLACE ALL OCCURRENCES OF 'ccc' IN text WITH 'ddd'
REPLACEMENT COUNT rcnt
REPLACEMENT OFFSET roff
REPLACEMENT LENGTH rlen.
"ddd: 2 6 3 替换值 new 未被截断且后面还有未进行替换处理的字符串(ccc),继续查找与替换
"dddd: 2 7 2 替换值 new 未被截断且后面还有未进行替换处理的字符串(cc),继续查找与替换
"ddddd: 2 8 1 替换值 new 未被截断且后面还有未进行替换处理的字符串(c),继续查找与替换
"dddddd: 1 3 6 替换值 new 未被截断但后面不再有其他字符串,所以不再查找与替换(替换次数1小于本应该查找到的次数2,因为在经过第1次替换后,被替代后面的所有字符串都会被截断,下面也是一样道理)
"ddddddd: 1 3 6 替换值 new 被截断,所以不再查找与替换
WRITE: / rcnt, / roff, / rlen.
[RESULTS result_tab|result_wa]
如果发生了替换操作,则替换的起始位置、匹配到的字符串长度都会存储到一个行结构为result_wa的result_tab内表中,与FIND中的RESULTS result_tab选项意思相当,只是result_tab and result_wa的类型为REPL_RESULT_TAB or REPL_RESULT,并且REPL_RESULT里没有内嵌SUBMATCHES:
替换指定位置
DATA: text1 TYPE string,
text2 TYPE c LENGTH 18,
off TYPE i,
len TYPE i.
text1 = text2 = 'I know you know'.
"先查找位置:查找第一次匹配位置
FIND 'know' IN text1 MATCH OFFSET off
MATCH LENGTH len.
"再根据指定位置替换
REPLACE SECTION OFFSET off LENGTH len OF:
text1 WITH 'should know that',
text2 WITH 'should know that'.
"text2替换后被截断
WRITE: / text1,/ text2 , sy-subrc.
I should know that you know
I should know that 2
DATA: text1 TYPE string,
cnt TYPE i,
off TYPE i,
len TYPE i.
text1 = 'I know you know'.
REPLACE ALL OCCURRENCES OF 'know' IN
SECTION OFFSET 11 LENGTH 4 of"在11~14索引范围内匹配替换
text1 WITH 'should know that'
REPLACEMENT COUNT cnt"发生的替换次数
REPLACEMENT OFFSET off"最后一次发生替换的位置
REPLACEMENT LENGTH len.
WRITE: / text1, cnt, off,len.
I know you should know that 1 11 16
使用正则式
DATA text TYPE string VALUE '-uu-'.
"字符间隙也会被看作是一个字符串元素,依照正则式,字符串首间隙、第二字符间隙被看作是满足正则式的,另外第三与第四字符间隙和两个 u 字符一起满足正则式(贪婪)
REPLACE ALL OCCURRENCES OF REGEX 'u*' IN text WITH 'x'.
WRITE: text.
x-xx-x
DATA: text1 TYPE string,
text2(18) TYPE c,
cnt TYPE i,
off TYPE i,
len TYPE i.
text1 = text2 = 'I know you know'.
REPLACE ALL OCCURRENCES OF 'know' IN:
text1 WITH 'should know that'
REPLACEMENT COUNT cnt"发生的替换次数
REPLACEMENT OFFSET off"最后一次发生替换的位置
REPLACEMENT LENGTH len.
WRITE: / text1, cnt, off,len.
"由于第一次替换后超出了 text2 本身的长度,所以不会再发生第二次替换
REPLACE ALL OCCURRENCES OF 'know' IN:
text2 WITH 'should know that'
REPLACEMENT COUNT cnt
REPLACEMENT OFFSET off
REPLACEMENT LENGTH len.
WRITE: / text2, cnt, off,len.
I should know that you should know that 2 23 16
I should know that 1 2 16
正则类
ABAP提供了两个类来支持正则式:
Regex class cl_abap_regex:与Java中的 java.util.regex.Pattern的类对应
Matcher class cl_abap_matcher:与Java中的 java.util.regex.Matcher的类对应
是否包含(也可在正则式中使用 ^ 与 $ 用于完全匹配检查,或者使用 ^ 检查是否匹配开头,或者使用 $ 匹配结尾),下面的TABLE参数表示需要在TABLE中进行索引,与TEXT是一样都是搜索源,如果TEXT与TABLE同时都指定时,会忽略TABLE:
与 CONTAINS 或 MATCHES 方法配合使用:
DATA: matcher TYPE REF TO cl_abap_matcher,
match TYPE match_result.
IF cl_abap_matcher=>matches( pattern = 'dbai.*' text = 'dbaiabd' ) = abap_true.
matcher = cl_abap_matcher=>get_object( ).
match = matcher->get_match( ).
WRITE / matcher->text+match-offset(match-length).
ENDIF.
是否完全匹配(正则式中不必使用 ^ 与 $):
DATA: matcher TYPE REF TO cl_abap_matcher,
match TYPE match_result,
itab TYPE match_result_tab,
line LIKE LINE OF itab.
matcher = cl_abap_matcher=>create( pattern = '<[^<>]*>' text = '<html>hello</html>' ).
itab = matcher->find_all( ).
LOOP AT itab INTO line.
WRITE: / matcher->text,line-offset,line-length,matcher->text+line-offset(line-length).
ENDLOOP.
INDEX为子匹配项(使用括号括起来的正则式)索引,默认为0,表示整体匹配正则式:
创建正则对象
DATA: regex TYPE REF TO cl_abap_regex,
matcher TYPE REF TO cl_abap_matcher.
l 直接Create
CREATE OBJECT regex EXPORTING pattern = 'a*b' ignore_case = abap_true.
CREATE OBJECT matcher EXPORTING regex = regex text = 'text'.
下面TEXT表示当前正被搜索的搜索源字符串,TABLE也是搜索源。如果TEXT与TABLE同时都指定时,会忽略TABLE。
l 使用静态工厂方法
matcher = cl_abap_matcher=>create( pattern = 'a*b' text = 'text' ).
相关文章:

ABAP正则表达式 特殊字符处理
REPLACE ALL OCCURRENCES OF REGEX [[:space:]] IN <fs_purhdinfo>-cell_value WITH ."可去掉空格或回车键 REPLACE ALL OCCURRENCES OF : IN <fs_purhdinfo>-cell_value WITH ."可去掉空格或回车键 REPLACE ALL OCCURRENCES OF R…...

【2024高教社杯全国大学生数学建模竞赛】ABCDEF题 问题分析、模型建立、参考文献及实现代码
【2024高教社杯全国大学生数学建模竞赛】ABCDEF题 问题分析、模型建立、参考文献及实现代码 1 比赛时间 北京时间:2024年9月5日 18:00-2024年9月8日20:00 2 思路内容 2.1 往届比赛资料 【2022高教社杯数学建模】C题:古代玻璃制品的成分分析与鉴别方案…...

# VMware 共享文件
VMware tools快速安装 VMware 提供了 open-vm-tools,这是 VMware 官方推荐的开源工具包,通常不需要手动安装 VMware Tools,因为大多数 Linux 发行版(包括 Ubuntu、CentOS 等)都包含了 open-vm-tools,并且已…...

[UVM]3.核心基类 uvm_object 域的自动化 copy() compare() print() pack unpack
1.核心基类:uvm_object (1)虚类只能声明,不能例化。 (2)uvm_object提供的方法 2.域的自动化(field automation) (1)简述 (2)示例 格…...

Java网络编程入门
在现代软件开发中,网络编程是一项不可或缺的技能。Java提供了强大的网络编程支持,使得开发者能够轻松地创建网络应用程序。今天将介绍Java中的网络编程基础,重点讲解Socket和ServerSocket类的使用。 什么是Socket? Socket是网络通…...

前端基础面试题·第三篇——JavaScript(其一)
1.JavaScript数据类型与运算符 数据类型 原始数据类型: 1.Number 2.String 3.Boolean 4.undefined 5.null 6.Symbol 7.bigint 复杂数据类型: 1.Function 2.非函数: Array: 数组 Object: 对象 Date: 日期 RegExp: 正则 Map: 映射 Set: 集合 …...

【机器学习】生成对抗网络(Generative Adversarial Networks, GANs)详解
1.引言 生成对抗网络(Generative Adversarial Networks, GANs)是近年来人工智能领域最具创新性和颠覆性的模型之一。自2014年由Ian Goodfellow及其团队提出以来,GAN的出现彻底改变了生成模型的研究范式。传统的生成模型,如变分自编码器(VAE)、隐马尔可夫模型(HMM)等,…...

QT作业1
1> 手写unique_ptr指针指针 代码: #include <iostream>using namespace std;// 自定义的unique_ptr类模板 template <typename T> class unique_ptr { public:// 构造函数,接收一个指针explicit unique_ptr(T* ptr nullptr) noexcept …...

Mybatis-设计模式总结
1、Builder模式 Builder模式的定义是“将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。”,它属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范围&#x…...

【笔记】Java | 三目运算符和Math函数的比较
实际效果 比较两数并赋值,如下两种方法的耗时不会有差异。 result Math.min(result, subLen);result result < subLen ? result : subLen; 源码解析 因为源码Math.min的源码本质就算三目运算符的比较,所以执行结果是一样的。 三目运算符简介 概…...

信创实践(2):利用Leapp工具迁移CentOS至AnolisOS,实现系统升级与自主可控
1. 引言 为了满足用户在CentOS退出后对操作系统使用的诉求,OpenAnolis龙蜥社区正式发布了Anolis OS。越来越多的CentOS客户期望能够迁移到Anolis OS上来。操作系统迁移是一个复杂工程,手工迁移技术要求高,操作复杂度强,需要耗费大…...

数据库死锁查询SQL
Oracle 从Oracle数据库的动态性能视图(Dynamic Performance Views)中检索当前被锁定的数据库对象的相关信息,以及持有这些锁的会话(session)的详细信息。具体来说,它连接了v$ session和v$locked_object两个…...

vLLM (4) - LLMEngine上篇
系列文章目录 vLLM (1) - Qwen2推理&部署 vLLM (2) - 架构总览 vLLM (3) - Sequence & SequenceGroup vLLM (4) - LLMEngine上篇 vLLM (5) - LLMEngine下篇 文章目录 系列文章目录前言一、类图二、LLM三、LLMEngine四、GPUExectuor五、Worker六、ModelRunner七、Cache…...

Java重修笔记 第五十天 HashSet 和 TreeSet 的去重机制比较
HashSet 和 TreeSet 的去重机制比较 1. HashSet 的去重机制:HashCode() equals() 。通过运算得到 key ,也就是该对象的哈希值,再通过哈希值得到该对象在 table 表上的索引位置,若该位置上没有链表数据就直接存放,若…...

提前购|基于SSM+vue的创新型产品提前购平台(源码+数据库+文档)
创新型产品提前购平台 基于SSMvue的创新型产品提前购平台 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员模块实现 发布企业管理实现 个体管理实现 投资企业管理实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…...

上海市计算机学会竞赛平台2024年7月月赛丙组求和问题
题目描述 给定 nn 个整数 a1,a2,…,ana1,a2,…,an,请问这个序列最长有多少长的前缀,满足元素的和大于或等于 00?如果任何长度大于 00 的前缀之和都为负数,则输出 00 输入格式 第一行:单个整数表示 nn第二行&a…...

【LVI-SAM】激光雷达点云处理特征提取LIO-SAM 之FeatureExtraction实现细节
激光雷达点云处理特征提取LIO-SAM 之FeatureExtraction实现细节 1. 特征提取实现过程总结1.0 特征提取过程小结1.1 类 FeatureExtraction 的整体结构与作用1.2 详细特征提取的过程1. 平滑度计算(calculateSmoothness())2. 标记遮挡点(markOcc…...

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2757 标注数量(xml文件个数):2757 标注数量(txt文件个数):2757 标注…...

opencart journal 3 在价格前添加文本prefix
要修改的文件: /catalog/view/theme/journal3/template/product.twig 行274: <div class="product-price">{{ price }}</div>{% else %}<div class="product-price-new">{{ special }}</div><div class="product-pric…...

c++ string类的模拟实现的注意事项
一.构造函数 第一种形式,使用字符指针赋值 为了防止修改,我们传入了常量字符串。但是这里的初始化列表出错了,因为_str是一个变量,将常量给到一个变量涉及到权限的放大,是错误的。那该怎么写呢?对_str的赋…...

Unity3D中控制3D场景中游戏对象显示层级的详解
前言 在Unity3D开发中,控制游戏对象的显示层级(也称为渲染顺序或渲染层级)是一个常见的需求,特别是在处理复杂的3D场景时,如角色、道具、UI元素等的可见性和渲染顺序的管理变得尤为重要。Unity通过几种不同的机制来实…...

代码执行漏洞-Log4j2漏洞 vulhub CVE-2021-44228
步骤一:执行以下命令启动靶场环境并在浏览器访问!!! 查看端口 浏览器访问 可以发现 /solr/admin/cores?action 这⾥有个参数可以传,可以按照上⾯的原理 先构造⼀个请求传过去存在JNDI注⼊那么ldap服务端会执⾏我们传上去的payload JDNI项⽬地址 https://github.com…...

uniapp / uniapp x UI 组件库推荐大全
在 uniapp 开发中,我们大多数都会使用到第三方UI 组件库,提起 uniapp 的UI组件库,我们最常使用的应该就是uview了吧,但是随着日益增长的需求,uview 在某些情况下已经不在满足于我们的一些开发需求,尽管它目…...

花8000元去培训机构学习网络安全值得吗,学成后就业前景如何?
我就是从培训机构学的网络安全,线下五六个月,当时学费不到一万,目前已成功入行。所以,只要你下决心要入这一行,过程中能好好学,那这8000就花得值~ 因为只要学得好,工作两个多月就能赚回学费&am…...

PhpStorm 下调试功能配置
调试是开发过程中的关键环节,能够极大地减少应用程序中的错误并提高代码质量。PhpStorm 作为一款功能强大的 IDE,提供了丰富的调试功能,结合 Xdebug,可以让开发者更轻松地进行 PHP 应用程序的调试。本指南将详细介绍如何在 PhpSto…...

MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)
1、MVC MVC(Model-View-Controller) 是一种常用的架构模式,用于分离应用程序的逻辑、数据和展示。它通过三个核心组件(模型、视图和控制器)将应用程序的业务逻辑与用户界面隔离,促进代码的可维护性、可扩展…...

【H2O2|全栈】关于HTML(4)HTML基础(三)
HTML相关知识 目录 HTML相关知识 前言 准备工作 标签的具体分类(三) 本文中的标签在什么位置中使用? 列表 编辑编辑 有序列表 无序列表 自定义列表 表格 拓展案例 预告和回顾 后话 前言 本系列博客将分享HTML相关知识点…...

关于找不到插件 ‘org.springframework.boot:spring-boot-maven-plugin:‘的解决方案
找到项目结构后,点击库,全选所有后点击应用即可...

深入RabbitMQ世界:探索3种队列、4种交换机、7大工作模式及常见概念
文章目录 文章导图RabbitMQ架构及相关概念四大核心概念名词解读 七大工作模式及四大交换机类型0、前置了解-默认交换机DirectExchange1、简单模式(Simple Queue)-默认DirectExchange2、 工作队列模式(Work Queues)-默认DirectExchange3、发布/订阅模式(Publish/Subscribe)-Fano…...

将目标检测模型导出到C++|RT-DETR、YOLO-NAS、YOLOv10、YOLOv9、YOLOv8
点击下方卡片,关注“小白玩转Python”公众号 最近,出现了更新的YOLO模型,还有RT-DETR模型,这是一个声称能击败YOLO模型的变换器模型,我想将这些模型导出并进行比较,并将它们添加到我的库中。在这篇文章中&a…...