perl正则表达式——递归模式

perl正则表达式——递归模式perl正则表达式递归模式模式引用

大家好,欢迎来到IT知识分享网。perl正则表达式——递归模式"

记录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

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信