【问题标题】:How to user Perl to find all instances of strings that match a regexp?如何使用 Perl 查找与正则表达式匹配的所有字符串实例?
【发布时间】:2012-01-19 05:59:25
【问题描述】:

如何使用 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.

【问题讨论】:

  • 请不要编辑问题作为回复 cmets 和答案的方式。

标签: regex perl


【解决方案1】:

问题在于/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 $_
}

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

您的版本,使用if,使用标量上下文,保存最近匹配的位置,但不会继续。一种查看发生情况的方法是:

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

pos 给出最近匹配的位置。

【讨论】:

  • @flesk 我想我应该写“最近的比赛”而不是“最后一场比赛”。
  • 为什么for ($text =~ /?[^.]\./g) 中的? 没有使用``?
  • @user001 我不明白你的意思,但我忘了在? 前面添加一个反斜杠。现在更新了。
  • @user001 我忘记添加量词了。 =) 现在修复它。
  • @TLP 为什么你更喜欢使用say 而不是print
【解决方案2】:

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

use Data::Dumper;

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

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

print Dumper(@arr);

预期结果:

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

【讨论】:

  • Dumper 喜欢获得参考,试试print Dumper \@arr
  • 我知道,但是对于这个例子没关系
【解决方案3】:

您似乎缺少/g 标志,它告诉perl 尽可能多地重复匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 2014-03-06
    相关资源
    最近更新 更多