1

我想知道模式匹配在 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

有人可以解释一下这种匹配是如何工作的吗?

4

4 回答 4

6

来自文档

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

因此,首先(.*)将尽可能多地占用。

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

于 2013-02-27T07:23:54.653 回答
4

贪心和不贪心匹配

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

于 2013-02-27T07:33:37.420 回答
1

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

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

所以:

  • (.*)\, 意思是:“匹配尽可能多的字符,只要后面有逗号”
  • (.*?)\, 意思是:“匹配任何字符,直到你偶然发现一个逗号”
于 2013-02-27T07:23:56.600 回答
0

(.*)\,- 你可能期望它会匹配到第一个逗号。但是它足够贪婪地匹配它遇到的所有 xcharacters,直到最后一个逗号而不是第一个逗号。所以它匹配到最后一个命令。第二场比赛是剩下的比赛。

避免贪婪模式匹配 adda?之后*

于 2013-02-27T07:41:10.817 回答