vka*_*ats 4 regex perl non-greedy regex-greedy
我有一个非贪婪的正则表达式的问题.我已经看到有关于非贪婪的正则表达式的问题,但他们没有回答我的问题.
问题:我试图匹配"lol"锚点的href.
注意:我知道这可以通过perl HTML解析模块完成,而我的问题不是在perl中解析HTML.我的问题是关于正则表达式本身,HTML只是一个例子.
测试用例:我有4个测试.*?
和[^"]
.2首先产生预期的结果.然而,第3次没有,第4次只是,但我不明白为什么.
问题:
.*?
和[^"]
?非贪婪的操作员不应该工作吗?.*?
和[^"]
?我不明白为什么包括.*
在前面改变正则表达式.(除了.*
前面的第3和第4次测试是相同的).我可能不明白这些正则表达式是如何工作的.一个perl食谱食谱提到了一些东西,但我不认为它回答了我的问题.
use strict;
my $content=<<EOF;
<a href="/hoh/hoh/hoh/hoh/hoh" class="hoh">hoh</a>
<a href="/foo/foo/foo/foo/foo" class="foo">foo </a>
<a href="/bar/bar/bar/bar/bar" class="bar">bar</a>
<a href="/lol/lol/lol/lol/lol" class="lol">lol</a>
<a href="/koo/koo/koo/koo/koo" class="koo">koo</a>
EOF
print "| $1 | \n\nThat's ok\n" if $content =~ m~href="(.*?)"~s ;
print "\n---------------------------------------------------\n";
print "| $1 | \n\nThat's ok\n" if $content =~ m~href="(.*?)".*>lol~s ;
print "\n---------------------------------------------------\n";
print "| $1 | \n\nWhy does not the 2nd non-greedy '?' work?\n"
if $content =~ m~href="(.*?)".*?>lol~s ;
print "\n---------------------------------------------------\n";
print "| $1 | \n\nIt now works if I put the '.*' in the front?\n"
if $content =~ m~.*href="(.*?)".*?>lol~s ;
print "\n###################################################\n";
print "Let's try now with [^]";
print "\n###################################################\n\n";
print "| $1 | \n\nThat's ok\n" if $content =~ m~href="([^"]+?)"~s ;
print "\n---------------------------------------------------\n";
print "| $1 | \n\nThat's ok.\n" if $content =~ m~href="([^"]+?)".*>lol~s ;
print "\n---------------------------------------------------\n";
print "| $1 | \n\nThe 2nd greedy still doesn't work?\n"
if $content =~ m~href="([^"]+?)".*?>lol~s ;
print "\n---------------------------------------------------\n";
print "| $1 | \n\nNow with the '.*' in front it does.\n"
if $content =~ m~.*href="([^"]+?)".*?>lol~s ;
Run Code Online (Sandbox Code Playgroud)
尝试打印$&
(与整个正则表达式匹配的文本)以及$1
.这可以让您更好地了解正在发生的事情.
你似乎遇到的问题是,.*?
这并不意味着"在这里使用最少字符的所有可能匹配中找到匹配".它只是意味着"首先,尝试在这里匹配0个字符,然后继续匹配其余的正则表达式.如果失败,请尝试匹配1个字符.如果正则表达式的其余部分不匹配,请在此处尝试2个字符.等等. "
Perl将始终找到最接近字符串开头的匹配项.由于你的大多数模式都是以href=
它开头的,它会找到href=
字符串中的第一个,看看是否有任何方法可以扩展重复以从那里开始匹配.如果它无法匹配,它将尝试从下一个开始href=
,依此类推.
当您.*
在正则表达式的开头添加贪婪时,匹配开始时.*
尽可能多地抓取字符.Perl然后回溯找到一个href=
.从本质上讲,这会导致它首先尝试字符串中的最后 href=
一个,并朝着字符串的开头工作.
归档时间: |
|
查看次数: |
1375 次 |
最近记录: |