大家好,欢迎来到IT知识分享网。
记录perl正则表达式之递归模式的个人理解
阅读前需要的基础:
1、perl在模式中引用一个捕获组时,这个组实际捕获的内容将用于反向引用。
/\b ( \p{alpha}+ ) \s+ \1 \b /x # numbered backref
/\b ( \p{alpha}+ ) \s+ \g{1} \b /x # alternate syntax
/\b ( \p{alpha}+ ) \s+ \g{–1} \b /x # relative backref
/\b (?<word> \p{alpha}+ ) \s+ \k<word> \b /x # named backref
2、扩展的正则表达式,本文中涉及到的部分
扩展 |
原子性 |
含义 |
(? <name>…) |
是 |
命名捕获分组 |
(?# …) |
否 |
注释,丢弃 |
(?: …) |
是 |
非捕获组 |
(?{…}) |
否 |
执行嵌入的perl代码 |
(?&name) |
是 |
在组name上递归,其引用的是模式,而不是匹配到的内容 |
匹配引擎递归匹配代码:
?1调用当前所在的组,导致引擎的递归处理,该代码是匹配平衡小括号的代码
/ ( \( (?: [^()]++ | (?1) )*+ \) )/x
[^()]++表示匹配非括号,当检测到有括号时进入分支(?1),调用整个模式自身,继续深入匹配。
想:用当前的模式去匹配第二条分支捕获到的内容,直到没有括号为止。
又想:如果是这样的话,那么次递归调用首先匹配的应该是‘\(’字符(左括号),那么这个模式就只能匹配一种字符串了,那就是”((((string))))”,但是实际上能匹配“aa(bb(cc(dd(ee))))”这种更复杂的,所以之前的想法不对。
递归:从内往外算
恩差点被正则匹配的形式忽悠了,递归递归。perl代码如下,做一个深入理解:
my $str = "aaa(s2s(rf(gt(3(eeeee)))))";
print "\nmatching!\n" if($str =~ /^ (?<p0> \w+ )
(?<pattern> (?#这里是第一个捕获组的开始)
\(
(?: (?<p1> [^()]++ ) (?#匹配非括号,并捕获) (?{print "< $` >|< $& >|< $' >\n";})
|
(?<p2> (?&pattern) )
)*+ (?#如果前一个分支失败,递归调用<pattern>命名组)
(?{ ($+{p0})?(print "p0:$+{p0}"):(print "p0:NULL");
($+{p1})?(print "\tp1:$+{p1}"):(print "\tp1:NULL");
($+{p2})?(print "\t\tp2:$+{p2}\n"):(print "\t\tp2:NULL\n")
}) (?#打印捕获的命名组 p1 p2)
(?#匹配非括号,并捕获) (?{print "< $` >|< $& >|< $' >\n";})
\)
) (?#第一个捕获组结束)
$/x);
{print “< $` >|< $& >|< $’ >\n”;} ## $`表示匹配到的串之前的串,$&表示匹配到的串,$’表示匹配到的串之后的串
分析输出结果如下:
#######这部分可以看到正则是如何一步步递归进入的#############
< >|< aaa(s2s >|< (rf(gt(3(eeeee))))) >
< >|< aaa(s2s(rf >|< (gt(3(eeeee))))) >
< >|< aaa(s2s(rf(gt >|< (3(eeeee))))) >
< >|< aaa(s2s(rf(gt(3 >|< (eeeee))))) >
< >|< aaa(s2s(rf(gt(3(eeeee >|< ))))) >
#####命名组p2是每次递归返回的捕获,p1是每次递归进入之前的捕获###############
p0:aaa p1:eeeee p2:NULL
< >|< aaa(s2s(rf(gt(3(eeeee >|< ))))) >
p0:aaa p1:3 p2:(eeeee)
< >|< aaa(s2s(rf(gt(3(eeeee) >|< )))) >
p0:aaa p1:gt p2:(3(eeeee))
< >|< aaa(s2s(rf(gt(3(eeeee)) >|< ))) >
p0:aaa p1:rf p2:(gt(3(eeeee)))
< >|< aaa(s2s(rf(gt(3(eeeee))) >|< )) >
p0:aaa p1:s2s p2:(rf(gt(3(eeeee))))
< >|< aaa(s2s(rf(gt(3(eeeee)))) >|< ) >
matching!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/21918.html