误解perl regexp评估
一天的美好时光!
我正在读一本关于perl的书:“编程Perl”由Larry Wall,Tom Christiansen,Jon Orwant撰写.在这本书中,我发现了几个作者没有澄清的例子(或者我当时没有得到). 首先 这仅打印ON. "adfsfloglig"=~ /.*(?{print "hi"})f/; 但这打印“嗨”TWICE ??怎么解释? "adfsfloglig"=~ /.*(?{print "hi"})log/; 继续经历甚至使事情变得更糟: "adfsfloglig"=~ /.*(?{print "hi"})sflog/; 上面的代码串再次打印ONCE这个可怕的“hi”! 第二个(这是炸弹!) $_ = "lothiernbfj"; m/ (?{$i = 0; print "setting i to 0n"}) (.(?{ local $i = $i + 1; print "ti is $i"; print "tWas founded $&n" }))* (?{print "nchecking rollbackn"}) er (?{ $result = $i; print "nsetting resultn"}) /x; print "final $resultn"; 这里最终在屏幕上打印的$result等于.*匹配的字符数,但我不再这样了. 当打开调试打印(如上所示)时,我看到,每当新的字符包含在$&中时,$i就会递增. (匹配的字符串部分). 最后,$i等于11(字符串中的字符数量),然后有7次回滚,当.*一次从其匹配字符串返回(7次),因此发生所有模式的匹配. 但是,该死的魔法,结果是设定为$i的价值!我们并没有在任何地方减少这个价值!所以$result应该等于11!但事实并非如此.作者是对的.我知道. 拜托,你能解释一下这个奇怪的perl代码,我很高兴见到了吗? 解决方法
从
http://perldoc.perl.org/perlre.html的文档:
即使在失败的匹配中,如果正则表达式引擎达到必须运行代码的程度,它也将运行代码.如果代码仅涉及分配给(本地?)变量以及允许的任何操作,则回溯将导致它撤消操作,因此失败的匹配将不起作用.但是打印操作无法撤消,结果是您可以从失败的匹配中打印字符串.这就是为什么文档警告不要嵌入带有“副作用”的代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |