[SAP ABAP开发技术总结]字符串处理函数、正则表达式

时间:2021-05-21 20:47:02
[SAP ABAP开发技术总结]字符串处理函数、正则表达式
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4263619.html

字符串处理是每门应用语言里都要掌握的,在SAP ABAP语言里也不例外,说到字符串处理,必然少不了正则式的出现,有了正则式,字符串才可以灵活处理,不过我在ABAP项目中看到的还都是使用的以前R3中老式的字符串处理语句。这节的内容是非常重要的,学好后,多复杂的字符串处理也不在话下。如果你以前学过其他语言正则式,比如Java中的正则式,这节内容看得就很轻松了。当然,正则式不是哪门语言特有的,正则式有如数据结构一样,只是使用不同语言去实现他而已,就是我一样,以前研究过Java中的正则式,然后在JavaScript中一样,最后到ABAP中,精髓还是一样,只是语句不同而已!

1.7.

字符串处理常用函数

...

7

1.7.1.

count

match

结合

...

7

1.7.2.

FIND …SUBMATCHES

.

8

1.7.3.

FIND …RESULTS  itab

.

8

1.7.4.

正则式类

...

9

1.7.4.1.

matches

match

.

9

1.7.4.2.

contains

.

10

1.7.4.3.

find_all

10

1.7.4.4.

find_next

.

11

1.7.4.5.

get_length

get_offset

get_submatch

.

11

1.7.4.6.

replace_all

12

1.7.

字符串处理常用函数

SPLIT

dobj

AT

sep

INTO

{ {result1 result2

...

} | {

TABLE

result_tab} }

必须指定足够目标字段。否则,用字段

dobj

的剩余部分填充最后目标字段并包含分界符;或者使用内表动态接收

SHIFT

dobj

{

[

{

BY

num

PLACES

}|{

UP

TO

sub_string}

][

[

LEFT

|

RIGHT

][

CIRCULAR

]

]

}

|

{

{LEFT DELETING LEADING

}|{

RIGHT DELETING TRAILING

}

}

pattern

对于固定长度字符串类型,

shift

产生的空位会使用空格或十六进制的

0

(如果为

X

类型串时)来填充

向右移动时前面会补空格,固定长度类型字符串与

String

结果是不一样:

String

类型右移后不会被截断,只是字串前面补相应数量的空格,但如果是

C

类型时,则会截断;左移后后面是否被空格要看是否是固定长度类型的字符串还是变长的

String

类型串,左移后

C

类型会补空格,

String

类型串不会(会缩短)

CIRCULAR

:将移出的字符串放在左边或者左边

pattern

:只要前导或尾部字符在指定的

pattern

字符集里就会被去掉,直到第一个不在模式

pattern

的字符止

CONDENSE

<c> [NO

-

GAPS]

.

如果是

C

类型只去掉前面的空格(因为是定长,即使后面空格去掉了,左对齐时后面会补上空格),如果是

String

类型,则后面空格也会被去掉;

字符串中间的多个连续的空格使用一个空格替换

(String

类型也是这样

)

NO-GAPS

:字符串中间的所有空格都也都会去除

(String

类型也是这样

)

;空格去掉后会左对齐

[k?n?dens]

CONCATENATE

{dobj1 dobj2

...

}|{

LINES

OF

itab}

[k?n?kat?ne?t]

INTO

result

            [

SEPARATED

BY

sep]

            [

RESPECTING

BLANKS

]

.

CDNT

类型的前导空格会保留,尾部空格都会被去掉,但对

String

类型所有空格都会保留;对于

c, d, n, t

类型的字符串有一个

RESPECTING BLANKS

选项可使用,表示尾部空格也会保留。注:
使用

``

String

类型进行赋值时才会保留尾部空格

字符串连接可以使用

&&

来操作,具体请参考这里

strlen

(

arg

)

Xstrlen(

arg

)

String

类型的尾部空格会计入字符个数中,但

C

类型的变量尾部空格不会计算入

substring

(

val

=

TEXT

[off

=

off] [len

=

len]

)

count

(

val

=

TEXT

{sub

=

substring}|{regex

=

regex}

)

匹配指定字符串

substring

或正则式

regex

出现的子串次数,返回的类型为

i

整型类型

contains

(

val

=

TEXT

REGEX

=

REGEX

)

是否包含。返回布尔值

,注:只能用在

if

While

等条件表达式中

matches

(

val

=

TEXT

REGEX

=

REGEX

)

regex

表达式要与

text

完全匹配

,这与

contains

是不一样的。返回布尔值,也只能用在

if

While

等条件表达式中

match

(

val

=

TEXT

REGEX

=

REGEX occ

=

occ

)

返回的为匹配到的字符串。注:每次只匹配一个。

occ

:表示需匹配到第几次出现的子串。如果为正,则从头往后开始计算,如果为负,则从尾部向前计算

find

(

val

=

TEXT

{sub

=

substring}|{regex

=

regex}[occ

=

occ]

)

查找

substring

或者匹配

regex

的子串的位置。如果未找到,则返回

-1

,返回的为

offset

,所以从

0

开始

FIND

ALL OCCURRENCES OF REGEX

regex

IN

dobj

  [

MATCH

COUNT

mcnt]

成功匹配的次数

{

{

[

MATCH OFFSET

moff][

MATCH

LENGTH

mlen]

}

最后一次整体匹配到的串(整体串,最外层分组,而不是指正则式最内最后一个分组)起始位置

与长度

|

[

RESULTS

result_tab|result_wa]

}

result_tab

接收所有匹配结果,

result_wa

只能接收最后一次匹配结果

[

SUBMATCHES

s1 s2

...

]

.

通常与前面的

MATCH OFFSET/ LENGTH

一起使用。只会接收使用括号进行分组的子组。如果变量

s1 s2 ...

比分组的数量多,则多余的变量被

initial

;如果变量

s1 s2 ...

比分组的数量少,则多余的分组将被忽略;且只存储第一次或最后一次匹配到的结果

replace

(

val

=

TEXT

REGEX

=

REGEX

WITH

=

NEW

)

使用

new

替换指定的子符串,返回

String

类型

REPLACE

ALL OCCURRENCES OF REGEX

regex

IN

dobj

WITH

new

1.7.1.

count

match

结合

DATA

:

text TYPE

string

VALUE

`Cathy's cat with the hat sat on Matt's mat.`

,

regx

TYPE

string

VALUE

`\<.at\>`

.

"\<

单词开头

\>

单词结尾

DATA

:

counts

TYPE i

,

index TYPE i

,

substr

TYPE

string

.

WRITE

/

text

.

NEW-LINE

.

counts

=

count

(

val

=

text

regex

=

regx

).

"

返回匹配次数

DO

counts

TIMES

.

index

=

find

(

val

=

text

regex

=

regx occ

=

sy

-

index

).

"

返回匹配到的的起始位置索引

substr

=

match

(

val

=

text

regex

=

regx occ

=

sy

-

index

).

"

返回匹配到的串

index

=

index

+

1

.

WRITE AT index

substr

.

ENDDO

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.2.

FIND …SUBMATCHES

DATA

:

moff

TYPE i

,

mlen

TYPE i

,

s1

TYPE

string

,

s2

TYPE

string

,

s3

TYPE

string

,

s4

TYPE

string

.

FIND ALL OCCURRENCES OF REGEX

`((\w+)\W+\2\W+(\w+)\W+\3)`

"\2 \3

表示反向引用前面匹配到的第二与第三个子串

IN

`

Hey hey, my my

, Rock and roll can never die

Hey hey, my my

`

"

会匹配二次,但只会返回第二次匹配到的结果,第一次匹配到的子串不会存储到

s1

s2

s3

中去

IGNORING

CASE

MATCH OFFSET

moff

MATCH LENGTH

mlen

SUBMATCHES

s1 s2 s3 s4

.

"

根据从外到内,从左到右的括号顺序依次存储到

s1 s2…

中,注:只取出使用括号括起来的子串,如想取整体子串则也要括起来,这与

Java

不同

WRITE

:

/  s1

,

/ s2

,

/ s3

,

/ s4

,

/ moff

,

/ mlen

.

"s4

会被忽略

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.3.

FIND …RESULTS  itab

DATA

:

result

TYPE STANDARD TABLE OF

string

WITH HEADER LINE

.

"

Java

不同,只要是括号括起来的都称为子匹配(即使用整体也用括号括起来了),

"

不管括号嵌套多少层,统称为子匹配,且匹配到的所有子串都会存储到,

"MATCH_RESULT-

SUBMATCHES

中,即使最外层的括号匹配到的子串也会存储到

SUBMATCHES

"

内表中。括号解析的顺序为:

从外到内,从左到右

的优先级顺序来解析匹配结构。

"Java

中的

group(0)

存储的是整体匹配串,即使整体未(或使用)使用括号括起来

PERFORM

get_match

TABLES

result

USING

'2011092131221032' '(((\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[]

.

"

result_tab

中存储了匹配到的子串本身

(与

Regex

整体匹配的串,存储在

"result_tab-offset

result_tab-length

中)

以及所子分组

(括号部分,存储在

"result_tab-submatches

中)

LOOP AT

result_tab

.

"

如需取整体匹配到的子串(与

Regex

整体匹配的串),则使用括号将整体

Regex

括起来

"

来即可,括起来后也会自动存储到

result_tab-submatches

,而不需要在这里像这样读取

*    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

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.4.

正则式类

regex =

Regular

expression

[?reɡjul?]

cl_abap_

regex

Java

中的

java.util.regex.

Pattern

的类对应

cl_abap_matcher


Java

中的

java.util.regex.

Matcher

的类对应

1.7.4.1.

matches

match

是否完全匹配

正则式中不必使用

^

$

);

matches

为静态方法

match

为实例方法

作用都是一样

DATA

:

matcher

TYPE REF TO

cl_abap_matcher

,

match

TYPE

match_result

,

match_line

TYPE

submatch_result

.

"

^$

可以省略

因为

matches

方法本身就是完全匹配整个

Regex

IF

cl_abap_matcher

=>

matches

(

pattern

=

'^(db(ai).*)$'

text

=

'dbaiabd'

) =

'X'

.

matcher

=

cl_abap_matcher

=>

get_object

( ).

"

获取最后一次匹配到的

Matcher

实例

match

=

matcher

->

get_match

( ).

"

获取最近一次匹配的结果

(

是整体匹配的结果

)

WRITE

/ matcher

->

text+match

-

offset

(

match

-

length

).

LOOP AT

match

-

submatches

INTO

match_line

.

"

提取子分组

括号括起来的部分

WRITE

:

/20 match_line

-

offset

,

match_line

-

length

,

matcher

->

text+match_line

-

offset

(

match_line

-

length

).

ENDLOOP

.

ENDIF

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

DATA

:

matcher

TYPE REF TO

cl_abap_matcher

,

match

TYPE

match_result

,

match_line

TYPE

submatch_result

.

"^$

可以省略,因为

matche

方法本身就是完全匹配整个

Regex

matcher

=

cl_abap_matcher

=>

create

(

pattern

=

'^(db(ai).*)$'

text

=

'dbaiabd'

).

IF

matcher

->

match

(  ) =

'X'

.

match

=

matcher

->

get_match

( ).

"

获取最近一次匹配的结果

WRITE

/ matcher

->

text+match

-

offset

(

match

-

length

).

LOOP AT

match

-

submatches

INTO

match_line

.

"

提取子分组(括号括起来的部分)

WRITE

:

/20 match_line

-

offset

,

match_line

-

length

,

matcher

->

text+match_line

-

offset

(

match_line

-

length

).

ENDLOOP

.

ENDIF

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.4.2.

contains

是否包含

也可在正则式中使用

^

$

用于完全匹配检查

或者使用

^

检查是否匹配开头

或者使用

$

匹配结尾

DATA

:

matcher

TYPE REF TO

cl_abap_matcher

,

match

TYPE

match_result

,

match_line

TYPE

submatch_result

.

IF

cl_abap_matcher

=>

contains

(

pattern

=

'(db(ai).{2}b)'

text

=

'dbaiabddbaiabb'

) =

'X'

.

matcher

=

cl_abap_matcher

=>

get_object

( ).

"

获取最后一次匹配到的

Matcher

实例

match

=

matcher

->

get_match

( ).

"

获取最近一次匹配的结果

WRITE

/ matcher

->

text+match

-

offset

(

match

-

length

).

LOOP AT

match

-

submatches

INTO

match_line

.

"

提取子分组(括号括起来的部分)

WRITE

:

/20 match_line

-

offset

,

match_line

-

length

,

matcher

->

text+match_line

-

offset

(

match_line

-

length

).

ENDLOOP

.

ENDIF

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.4.3.

find_all

一次性找出所有匹配的子串,包括子分组(括号括起的部分)

DATA

:

matcher

TYPE REF TO

cl_abap_matcher

,

match_line

TYPE

submatch_result

,

itab

TYPE

match_result_tab

WITH HEADER LINE

.

matcher

=

cl_abap_matcher

=>

create

(

pattern

=

'<[^<>]*(ml)>'

text

=

'<html>hello</html>'

).

"

创建

matcher

实例

"

:子分组存储在

itab-submatches

字段里

itab

[]

=

matcher

->

find_all

( ).

LOOP AT

itab

.

WRITE

:

/ matcher

->

text

,

itab

-

offset

,

itab

-

length

,

matcher

->

text+itab

-

offset

(

itab

-

length

).

LOOP AT

itab

-

submatches

INTO

match_line

.

"

提取子分组(括号括起来的部分)

WRITE

:

/20 match_line

-

offset

,

match_line

-

length

,

matcher

->

text+match_line

-

offset

(

match_line

-

length

).

ENDLOOP

.

ENDLOOP

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.4.4.

find_next

逐个找出匹配的子串,包括子分组(括号括起的部分)

DATA

:

matcher

TYPE REF TO

cl_abap_matcher

,

match

TYPE

match_result

,

match_line

TYPE

submatch_result

,

itab

TYPE

match_result_tab

WITH HEADER LINE

.

matcher

=

cl_abap_matcher

=>

create

(

pattern

=

'<[^<>]*(ml)>'

text

=

'<html>hello</html>'

).

WHILE

matcher

->

find_next

( ) =

'X'

.

match

=

matcher

->

get_match

( ).

"

获取最近一次匹配的结果

WRITE

:

/ matcher

->

text

,

match

-

offset

,

match

-

length

,

matcher

->

text+match

-

offset

(

match

-

length

).

LOOP AT

match

-

submatches

INTO

match_line

.

"

提取子分组(括号括起来的部分)

WRITE

:

/20 match_line

-

offset

,

match_line

-

length

,

matcher

->

text+match_line

-

offset

(

match_line

-

length

).

ENDLOOP

.

ENDWHILE

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.4.5.

get_length

get_offset

get_submatch

DATA

:

matcher

TYPE REF TO

cl_abap_matcher

,

length

TYPE i

,

offset

TYPE i

,

submatch

TYPE

string

.

matcher

=

cl_abap_matcher

=>

create

(

pattern

=

'(<[^<>]*(ml)>)'

text

=

'<html>hello</html>'

).

WHILE

matcher

->

find_next

( ) =

'X'

.

"

循环

2

"

0

时,表示取整个

Regex

匹配到的子串,这与

Java

一样,但如果整个

Regex

使用括号括起来后,

"

则分组索引为

1

,这又与

Java

不一样(

Java

不管是否使用括号将整个

Regex

括起来,分组索引号都为

0

"

上面

Regex

*有两个子分组,再加上整个

Regex

为隐含分组,所以一共为

3

DO

3

TIMES

.

"

在当前匹配到的串(整个

Regex

相匹配的串)中返回指定子分组的匹配到的字符串长度

length

=

matcher

->

get_length

(

sy

-

index

-

1

).

"

在当前匹配到的串(整个

Regex

相匹配的串)中返回指定子分组的匹配到的字符串起始位置

offset

=

matcher

->

get_offset

(

sy

-

index

-

1

).

"

在当前匹配到的串(整个

Regex

相匹配的串)中返回指定子分组的匹配到的字符串

submatch

=

matcher

->

get_submatch

(

sy

-

index

-

1

).

WRITE

:

/ length

,

offset

,

matcher

->

text+offset

(

length

),

submatch

.

ENDDO

.

SKIP

.

ENDWHILE

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式

1.7.4.6.

replace_all

DATA

:

matcher

TYPE REF TO

cl_abap_matcher

,

count

TYPE i

,

repstr

TYPE

string

.

matcher

=

cl_abap_matcher

=>

create

(

pattern

=

'<[^<>]*>'

text

=

'<html>hello</html>'

).

count

=

matcher

->

replace_all

(

``

).

"

返回替换的次数

repstr

=

matcher

->

text

.

"

获取被替换后的新串

WRITE

:

/

count

,

repstr

.

[SAP ABAP开发技术总结]字符串处理函数、正则表达式