我正在阅读关于正则表达式的具体示例/练习 要处理的句子是:
<b>Billions</b> and <b>Zillions</b> of suns
所需的匹配是Billions
,即<b></b>
之间的文字
该解决方案提出了2个正则表达式:
第一:
<b>((?!<b>).)*?</b>
我不明白为什么这里需要懒惰的量词。在我看来,这是多余的
然后第二个解决方案提出以下内容,以便能够删除惰性限定符:
第二:
<b>((?!</?b>).)*?</b>
我能理解第二种解决方案,但对我而言,解决与懒惰有关的任何问题似乎都是无关紧要的。我的意思是:
<b>((?!<b>).)*</b>
据我所知,它会匹配Billions
就好了。它将贪婪地达到Zillions的<b>
,然后它将开始回溯直到达到Billions的</b>
并达到匹配。
示例:
$ perl -e '
my $var = "<b>Billions</b> and <b>Zillions</b> of suns";
$var =~ /<b>(((?!<b>).)*)<\/b>/;print "$1\n";
'
Billions
我在这里误解了什么吗? 可能是作者试图编写一个对所有工具都有效的正则表达式吗?
答案 0 :(得分:0)
<b>((?!<b>).)*?</b>
和<b>((?!<b>).)*</b>
之间的区别仅在于性能和所涉及的回溯量。
第一个正则表达式将与您的示例句中的Billions
匹配并停在那里。
第二个正则表达式将匹配Billions and
,然后在找到匹配项之前开始回溯。因此第二个效率降低。但是如果你再看一遍,如果没有嵌套标签(例如<b>.*?</b>
,那么如果包含要回溯的字符数,则正则表达式在匹配的字符数方面也可以相当于<b>Billions and <b>Zillions</b></b> of suns
。但这很愚蠢,因为嵌套的<b>
不会改变格式。)
我自己会用:
<b>((?!</b>).)*</b>
作为正则表达式。否定前瞻中的</b>
会阻止</b>
的匹配,最终比第一个正则表达式更有效。
例如,您可以看到在获得以下匹配项之前所采取的“步骤”数量: