【问题标题】:How does pattern matching work in Perl?Perl 中的模式匹配是如何工作的?
【发布时间】:2013-02-12 21:58:03
【问题描述】:

我想知道模式匹配在 Perl 中是如何工作的。

我的代码是:

my $var = "VP KDC T. 20, pgcet. 5, Ch. 415, Refs %50 Annos";

if($var =~ m/(.*)\,(.*)/sgi)
{
    print "$1\n$2";
}

我了解到应该匹配第一次出现的逗号。但这里最后一次匹配。我得到的输出是:

VP KDC T. 20, pgcet. 5, Ch. 415
 Refs %50 Annos

谁能解释一下这种匹配是如何工作的?

【问题讨论】:

  • @all,非常感谢您的回答和解释。他们帮助我获得了一些关于 .* 和 .* 的知识?
  • 如果您认为您的问题回答正确,请标记答案。
  • 请接受正确答案,否则人们可能没有兴趣回答您的问题!
  • @Krishna 我不知道如何标记答案。如果您的意思是赞成或反对,我没有必要的声誉来投票。

标签: regex perl pattern-matching


【解决方案1】:

来自docs

默认情况下,量化的子模式是“贪婪的”,也就是说,它会尽可能多地匹配(给定一个特定的起始位置),同时仍然允许模式的其余部分匹配

所以,首先(.*) 会尽可能多地占用。

简单的解决方法是使用非贪婪量词:*?。或者不是匹配每个字符,而是除逗号之外的所有字符:([^,]*)

【讨论】:

  • [^,]*.*? 更强大,我会选择[^,]*
【解决方案2】:

在你的正则表达式中使用问号:

if($var =~ m/(.*?)\,(.*)/sgi)
{
    print "$1\n$2";
}

所以:

  • (.*)\,意思是:“匹配尽可能多的字符,只要后面有逗号”
  • (.*?)\,意思是:“匹配任何字符,直到你偶然发现一个逗号”

【讨论】:

    【解决方案3】:

    贪婪和非贪婪匹配

    Perl 正则表达式通常匹配可能的最长字符串。

    例如:

    my($text) = "mississippi";
    $text =~ m/(i.*s)/;
    print $1 . "\n";
    

    运行前面的代码,你会得到:

    ississ
    

    它匹配第一个 i,最后一个 s,以及它们之间的所有内容。但是,如果您想将第一个 i 与最接近它的 s 匹配怎么办?使用此代码:

    my($text) = "mississippi";
    $text =~ m/(i.*?s)/;
    print $1 . "\n";
    

    现在看看代码产生了什么:

    is
    

    显然,问号的使用使匹配变得不贪心。但是还有一个问题是正则表达式总是尽可能早地匹配。

    来源:http://www.troubleshooters.com/codecorn/littperl/perlreg.htm

    【讨论】:

      【解决方案4】:

      (.*)\, - 你可能认为它会匹配到第一个逗号。 但是它足够贪婪地匹配它遇到的所有 xcharacters,直到最后一个逗号而不是第一个逗号。 所以 它匹配到最后一个命令。 第二个匹配是该行的其余部分。

      为了避免贪婪的模式匹配在?之后添加*

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-06
        • 2016-10-04
        • 1970-01-01
        相关资源
        最近更新 更多