如何使用Perl查找与regexp匹配的所有字符串实例?

时间:2012-01-18 19:34:18

标签: regex perl

如何使用Perl查找和打印与正则表达式匹配的所有字符串?

以下仅查找第一场比赛。

$text="?Adsfsadfgaasdf.
?Bafadfdsaadsfadsf.
xcxvfdgfdg";

if($text =~ m/\\?([^\.]+\.)/) {
    print "$1\n";
}

EDIT1:/g不起作用

#!/usr/bin/env perl

$text="?Adsfsadfgaasdf.
?Bafadfdsaadsfadsf.
xcxvfdgfdg";

if($text =~ m/\\?([^\.]+\.)/g) {
    print "$1\n";
}

$ ./test.pl 
?Adsfsadfgaasdf.

3 个答案:

答案 0 :(得分:9)

问题是/g修饰符不会将捕获组用于多个匹配。您需要在标量上下文中迭代匹配,或者在列表上下文中捕获返回的列表。例如:

use v5.10; # required for say()
$text="?Adsfsadfgaasdf.
?Bafadfdsaadsfadsf.
xcxvfdgfdg";

while ($text =~ /\?([^.]+\.)/g) {  # scalar context
    say $1;
}
for ($text =~ /\?[^.]+\./g) {     # list context
    say;               # match is held in $_
}

注意在第二种情况下,我跳过了parens,因为在列表上下文中,如果没有parens,则返回整个匹配。您可以添加parens来选择字符串的一部分。

您的版本使用if,使用标量上下文,可以保存最近一次匹配的位置,但不会继续。看看会发生什么的方法是:

if($text =~ m/\?([^\.]+\.)/g) {
    print "$1\n";
}
say "Rest of string: ", substr $text, pos;

pos给出了最近一场比赛的位置。

答案 1 :(得分:2)

在之前的回答中,@ TLP正确地写道,匹配应该在列表上下文中。

use Data::Dumper;

$text="?Adsfsadfgaasdf.
?Bafadfdsaa.
dsfadsf.
xcxvfdgfdg";

@arr = ($text =~ /\?([^\.]+\.)/g);

print Dumper(@arr);

预期结果:

$VAR1 = 'Adsfsadfgaasdf.';
$VAR2 = 'Bafadfdsaa.';

答案 2 :(得分:0)

你似乎错过了/g标志,它告诉perl尽可能多次重复匹配。