文档库 最新最全的文档下载
当前位置:文档库 › ABAP正则表达式

ABAP正则表达式

正则表达式(Regular Expressions)

正则表达式在其他编程语言中的应用非常广泛,网上资料也非常多,而网上在ABAP语言中应用的资料却

很少,尽管各语言中正则表达式语法知识都很类似,但仍然有一些区别,本文主要是简单介绍一下其基本

语法。总结一下,方便大家查阅。

欢迎转载,请注明出处,文中不足之处还望指正。(Email:hubin0809@https://www.wendangku.net/doc/ea1619900.html,)

一、简要认识

正则表达式就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如表

达式“ab+”描述的特征是“一个 'a' 和任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。

正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。(2)用来

查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。(3)用来

替换,比普通的替换更强大。

举例

解释:

1> '\w+@\w+(\.\w+)+'中 \w 是表示任意一个字母或数字或下划线,+ 表示前面字符个数为一个或多个,@即为’@’字符

2> matcher参照类cl_abap_matcher,match有匹配的意思,调用静态方法create创建了匹配的

对(暂时这么理解,好吧,我承认我不知道怎么形容),然后调用match方法,返回值中’X’表示匹配,SPACE表示不匹配。

具体含义后面会讲到,本程序主要是验证邮件地址是否合法。

二、语法规则

pattern模板,text要匹配的字符,match匹配结果,’X’表示匹配,SPACE表示不匹配。

1、普通字符

字母、数字、汉字、下划线、以及后面没有特殊定义的标点符号,都是"普通字符"。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。

2、转义字符

一些不便书写的字符,采用在前面加 "\" 的方法。例如’.’

3、能够与 '多种字符' 匹配的表达式

正则表达式中的一些表示方法,可以匹配 '多种字符' 其中的任意一个字符。比如,表达式 "\d" 可以匹配任意一个数字。虽然可以匹配其中任意字符,但是只能是一个,不是多个。这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。(没玩过?好吧,去玩qq够级吧,ok,信息泄露了,承认我是山东人)

4、自定义能够与 '多种字符' 匹配的表达式

使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。

5、支持的 POSIX 字符集合

个人感觉意义不大,可能对一些控制字符有用吧,了解。

6、修饰匹配次数的特殊符号

前面讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配,否则会累死的。

7、其他一些代表抽象意义的特殊符号

进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。

举例1:表达式 "^aaa" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。因为 "^" 要求与字符串开始

的地方匹配,因此,只有当 "aaa" 位于字符串的开头的时候,"^aaa" 才能匹配,比如:"aaa xxx xxx"。

举例2:表达式 "aaa$" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。因为 "$" 要求与字符串结束

的地方匹配,因此,只有当"aaa" 位于字符串的结尾的时候,"aaa$" 才能匹配,比如:"xxx xxx aaa"。举例3:表达式 ".\b." 在匹配 "@@@abc" 时,能够找到匹配的内容;匹配到的内容是:"@a";匹配

到的位置是:开始于2,结束于4。

进一步说明:"\b" 与 "^" 和 "$" 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的

左右两边,其中一边是 "\w" 范围,另一边是非"\w" 的范围。

举例4:表达式 "\bend\b" 在匹配 "weekend,endfor,end" 时,能够找到匹配的内容;匹配到的内容是:"end";匹配到的位置是:开始于15,结束于18。

三、正则表达式中的一些高级规则(ABAP部分支持)

1、匹配次数中的贪婪与非贪婪

贪婪模式:

在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表

达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 "dxxxdxxxd",举例如下:

由此可见,"\w+" 在匹配的时候,总是尽可能多的匹配符合它规则的字符。虽然第二个举例中,它没有匹

配最后一个 "d",但那也是为了让整个表达式能够匹配成功。同理,带 "*" 和 "{m,n}" 的表达式都是尽

可能地多匹配,带 "?" 的表达式在可匹配可不匹配的时候,也是尽可能的 "要匹配"。这种匹配原则就叫作"贪婪" 模式。

非贪婪模式:(ABAP暂时不支持,但是最好理解吧)

在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使

可匹配可不匹配的表达式,尽可能的 "不匹配"。这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。

如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。举例如下,针对文本 "dxxxdxxxd" 举例:

更多的情况,举例如下:

举例1:表达式 "(.*)" 与字符串 "

aa

< td>

bb

" 匹配时,匹配的结果是:成功;匹配到的内容是 "

aa

< td>

bb

" 整个字符串,表达式中的 "" 将与字符串中最后一个 "" 匹配。

举例2:相比之下,表达式 "(.*?)" 匹配举例1中同样的字符串时,将只得到

"

aa

",再次匹配下一个时,可以得到第二个 "

bb

"。

2、反向引用 \1, \2

表达式在匹配时,表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录下来。在获取匹配结

果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展

示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来

指定所要的范围。比如前面的 "(.*?)"。

其实,"小括号包含的表达式所匹配到的字符串" 不仅是在匹配结束后才可以使用,在匹配过程中也可以

使用。表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。引用方法是 "\" 加上一

个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,

如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一

对就先排序号。

举例如下:

举例1:表达式 "('|")(.*?)\1" 在匹配 " 'Hello', "World" " 时,匹配结果是:成功;匹配到的内容是:" 'Hello' "。再次匹配下一个时,可以匹配到 " "World" "。

举例2:表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,匹

配结果是:成功;匹配到的内容是 "ccccc"。再次匹配下一个时,将得到 999999999。这个表达式要求"\w" 范围的字符至少重复5次,注意与 "\w{5,}" 之间的区别。

举例3:表达式 "<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?" 在匹配 "

style="bgcolor:white">" 时,匹配结果是成功。如果 "" 与 "" 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。

3、预搜索

前面的章节中,我讲到了几个代表抽象意义的特殊符号:"^","$","\b"。它们都有一个共同点,那就是:它们本身不匹配任何字符,只是对 "字符串的两头" 或者 "字符之间的缝隙" 附加了一个条件。理解到这个

概念以后,本节将继续介绍另外一种对 "两头" 或者 "缝隙" 附加条件的,更加灵活的表示方法。

正向预搜索:"(?=xxxxx)","(?!xxxxx)"

格式:"(?=xxxxx)",在被匹配的字符串中,它对所处的 "缝隙" 或者 "两头" 附加的条件是:所在缝隙的右侧,必须能够匹配上 xxxxx 这部分的表达式。因为它只是在此作为这个缝隙上附加的条件,所以它并不影响后边的表达式去真正匹配这个缝隙之后的字符。这就类似 "\b",本身不匹配任何字符。"\b" 只是将所在缝隙之前、之后的字符取来进行了一下判断,不会影响后边的表达式来真正的匹配。

举例1:表达式 "Windows (?=NT|XP)" 在匹配 "Windows 98, Windows NT, Windows 2000" 时,将只匹配 "Windows NT" 中的 "Windows ",其他的 "Windows " 字样则不被匹配。

举例2:表达式 "(\w)((?=\1\1\1)(\1))+" 在匹配字符串 "aaa ffffff 999999999" 时,将可以匹配6个"f"的前4个,可以匹配9个"9"的前7个。这个表达式可以读解成:重复4次以上的字母数字,则匹配其剩下最后2位之前的部分。当然,这个表达式可以不这样写,在此的目的是作为演示之用。

格式:"(?!xxxxx)",所在缝隙的右侧,必须不能匹配 xxxxx 这部分表达式。

举例3:表达式 "((?!\bstop\b).)+" 在匹配 "fdjka ljfdl stop fjdsla fdj" 时,将从头一直匹配到"stop" 之前的位置,如果字符串中没有 "stop",则匹配整个字符串。

举例4:表达式 "do(?!\w)" 在匹配字符串 "done, do, dog" 时,只能匹配 "do"。在本条举例中,"do" 后边使用 "(?!\w)" 和使用 "\b" 效果是一样的。

4、其他补充

1> 在表达式 "\s","\d","\w","\b" 表示特殊意义的同时,其大写字母表示相反的意义

2> 在表达式中有特殊意义,需要添加 "\" 才能匹配该字符本身的字符汇总

四、在ABAP中的应用

规则终于写完了!其实和其他编程语言规则差不多啦!下面结合ABAP讲讲怎么使用吧,Let’s GO! 不过需要注意, SAP只能是ECC6或者更高版本才可以使用正则(ABAP supports POSIX regular expressions as of Release 7.00)

在ABAP中定义了两个类来实现相应功能,分别是

CL_ABAP_REGEX regex就是regular expression的缩写,里面的方法不是很多,可能用到的也就只有构造方法和REATE_MATCHER这个方法。

CL_ABAP_MATCHER matcher匹配的意思,也就是说所有的匹配规则都和它有关,里面具体方法,se24去查看

其实正则表达式的应用无外乎三种:验证(是否符合规则)、查找(包含提取)、替换

1、验证

实例1

解释:CL_ABAP_MATCHER有一个静态方法,直接进行匹配。

2、查找

实例2

解释:

1.创建match实例(创建规则),构造方法中有pattern参数输

入规则,IGNORE_CASE是否忽略大小写,SIMPLE_REGEX

是否使用简单规则(具体参见F1帮助文档),

B.在实例中有FIND_ALL(),FIND_NEXT()方法,可以用来查找。

这个方法是不是太麻烦了啊,不急有简单的方法,其实就是字符串处理中用到的。

实例3

实例4

解释:大家都知道英文字母是单字节的,中文是双字节的,但是在ABAP里面用strlen等方法是区别不出单双字节的,这个实例中讲的不失为一个很好的办法。

3、替换

实例4

大家肯定会说了,字符串前后没有没替换啊。注意修改的不是W_TEXT本身,他将修改后的值放到了MATCHER->TEXT即match类实例的属性里面,我们只需令W_TEXT = MATCHER->TEXT即可。

修改后

同样这里也有简单方法,字符串处理中的方法也是支持正则的

实例5

4、方法语句总结

类结

CL_ABAP_MATCHER类里的重要方法

字符串处理中,支持正则的语句

五、补充

这里给出ABAP F1帮助中给出的一个特殊字符的列表,很有用的Special Characters in Regular Expressions

The following tables summarize the special characters in regular expressions: Escape character

Special character for single character strings

Special characters for character string patterns

Special characters for search strings

Special characters for replacement texts

从上面的列表可以看出,ABAP中对“非贪婪模式”(ABAP啊,你不支持啊,你太贪婪了)和“反向预搜索”暂不支持,希望以后能够赶紧扩展功能吧,毕竟很强大的说。

正则表达式是需要反复修改,最后才能找到最匹配的规则的,为此ABAP Program里也提供了一个,测试用得小程序,SE38里找DEMO_REGEX_TOY运行即可。

在ABAP培训资料里面有一个很有意思的表达式,大家有兴趣可以看一下它能匹配什么文字

以下附上网上的一些资料:

表达式全集

正则表达式有多种不同的风格。下表是在PCRE中元字符及其在正则表达式上下文中的行为的一个完整列表:

相关文档
相关文档 最新文档