为什么我的Perl正则表达式与我认为它应该匹配?

时间:2010-01-18 06:39:16

标签: regex perl

我尝试了Robert的Perl教程(link text)中的以下代码片段:

> $_='My email address is
> <webslave@work.com>.';
> 
> print "Found it ! :$1:" if /(<*>)/i;

当我运行它时,输出是:

  发现它!产品:&gt;:

但是,输出不应该是,

  发现它! :M GT;:

因为'm'匹配“0或更多”&lt;'即正则表达式的'&lt; *'部分“

此外,

$_='My email address is <webslave@work.com>.';
print "Match 1 worked :$1:" if /(<*)/i;

运行此命令时输出为:

  

匹配1工作::

$_='<My email address is <webslave@work.com>.';
print "Match 2 worked :$1:" if /(<*)/i;

运行上述操作时,输出为:

  

匹配2工作:&lt;:

但输出不应该是:

  

比赛2工作::

因为第一场比赛(即$ 1)是“”而不是“&lt;”,就像之前的例子一样。

5 个答案:

答案 0 :(得分:4)

if /(<*>)/i;

将匹配0或更多&lt;字符,紧接着是&gt;炭...

所以唯一可能的匹配是&gt; char前面的0&lt;字符。

答案 1 :(得分:3)

你的第一个问题的答案很简单,你错了。

第二个问题相当有趣,要理解这一点,你需要知道两个事实:

  1. 一旦成功匹配,正则表达式将停止匹配并返回它认为成功的结果。
  2. 标准量词(* + ?{min, max})贪婪。这意味着/<*/将匹配尽可能多的<<<<<...
  3. 所以,回到正则表达式/<*/。匹配时

    My email address is <webslave@work.com>.
    

    字符串的最开头^与正则表达式匹配,后者产生一个空字符串。这是一次成功的匹配,下一步^M与您的正则表达式不匹配。所以瞧,perl会停止匹配并给你空洞的结果。

    然后来到第二个字符串

    <My email address is <webslave@work.com>.
    

    字符串的最开头^与正则表达式匹配,后者产生一个空字符串。 ,下一步^<仍与您的正则表达式匹配。和quntifier *是贪婪的。它将尽可能匹配。因此导致<

答案 2 :(得分:2)

使用$ 1,您可以访问正则表达式的第一个“捕获”,捕获是在括号之间放置的。在你的例子中,我认为你错过了一个。 <*>匹配零个或多个'&lt;'字符后跟'&gt;'字符,所以这里匹配零'&lt;'和一个'&gt;'。它可能应该是这样的:

print "Found it ! :$1:" if /(<.*>)/i;

现在这匹配'&lt;'后跟零个或多个任意字符('。'匹配任何字符),后跟'&gt;'。

答案 3 :(得分:1)

Perl中的正则表达式与许多OS应用程序中的通配符略有不同。

*表示“之前的0或更多”。所以当你这样做时

<*>

IT意味着

“零或多于字符,后跟大于字符。”

你想要的是正则表达式用户最好的朋友:.

<.*>

这意味着

“小于字符,后跟任意0次或更多次,后跟大于字符。”

但这可能不是你的意思:>字符也是“任何字符”!幸运的是,有一个简单的方法可以说明你的真正含义*不再贪婪?字符:

<.*?>

这意味着,“小于字符,后跟任何东西,0次或更多次,直到我达到&gt;字符。”

呜!

有一些很棒的网站可以让你熟悉正则表达式的世界,我最喜欢的是regular expressions.info。但是对于perl特定的正则表达式,你无法击败经典的Perl Regular Expressions Tutorial。 perl正则表达式教程已经引导了许多正则表达式流浪者到Perl家园,并且是一个很好的资源。

答案 4 :(得分:0)

我个人非常喜欢cheat sheet at Added Bytes