加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式 – perl非贪心问题

发布时间:2020-12-14 05:58:03 所属栏目:百科 来源:网络整理
导读:我有一个非贪婪的正则表达式的问题.我已经看到有关于非贪婪的正则表达式的问题,但他们没有回答我的问题. 问题:我试图匹配“lol”锚点的href. 注意:我知道这可以通过perl HTML解析模块完成,而我的问题不是在perl中解析HTML.我的问题是关于正则表达式本身,HT
我有一个非贪婪的正则表达式的问题.我已经看到有关于非贪婪的正则表达式的问题,但他们没有回答我的问题.

问题:我试图匹配“lol”锚点的href.

注意:我知道这可以通过perl HTML解析模块完成,而我的问题不是在perl中解析HTML.我的问题是关于正则表达式本身,HTML只是一个例子.

测试用例:我有4个测试.*?和[^“].第一个产生预期的结果.然而第三个没有,第四个只是,但我不明白为什么.

问题:

>为什么第三次测试在两个测试中都失败了.*?和[^“]?非贪婪的运算符不应该工作吗?
>为什么第四次测试在两个测试中都有效.*?和[^“]?我不明白为什么在前面包含一个.*来改变正则表达式.(第三和第四个测试除了前面的.*之外是相同的).

我可能不明白这些正则表达式是如何工作的.一个perl cookbook recipe提到的东西,但我不认为它回答了我的问题.

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 | nnThat's okn" if $content =~ m~href="(.*?)"~s ;

print "n---------------------------------------------------n";

print "| $1 | nnThat's okn" if $content =~ m~href="(.*?)".*>lol~s ;

print "n---------------------------------------------------n";

print "| $1 | nnWhy does not the 2nd non-greedy '?' work?n"
  if $content =~ m~href="(.*?)".*?>lol~s ;

print "n---------------------------------------------------n";

print "| $1 | nnIt 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###################################################nn";


print "| $1 | nnThat's okn" if $content =~ m~href="([^"]+?)"~s ;

print "n---------------------------------------------------n";

print "| $1 | nnThat's ok.n" if $content =~ m~href="([^"]+?)".*>lol~s ;

print "n---------------------------------------------------n";

print "| $1 | nnThe 2nd greedy still doesn't work?n"
  if $content =~ m~href="([^"]+?)".*?>lol~s ;

print "n---------------------------------------------------n";

print "| $1 | nnNow with the '.*' in front it does.n"
  if $content =~ m~.*href="([^"]+?)".*?>lol~s ;

解决方法

尝试打印$& (整个正则表达式匹配的文本)以及$1.这可以让您更好地了解正在发生的事情.

你似乎遇到的问题是.*?并不意味着“在这里使用最少字符的所有可能匹配中找出匹配.”它只是意味着“首先,尝试在这里匹配0个字符,然后继续匹配其余的正则表达式.如果失败,请尝试匹配1个字符.如果正则表达式的其余部分不匹配,请在此处尝试2个字符.等等. “

Perl将始终找到最接近字符串开头的匹配项.由于大多数模式都以href =开头,因此它会在字符串中找到第一个href =并查看是否有任何方法可以扩展重复以从此处开始匹配.如果它无法匹配,它将尝试从下一个href =开始,依此类推.

当你在正则表达式的开头添加一个贪婪的.*时,匹配开始于.*抓取尽可能多的字符.然后Perl回溯找到一个href =.从本质上讲,这会导致它首先尝试字符串中的最后一个href =,并朝着字符串的开头工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读