【问题标题】:How to use regex match to find a string in an array of patterns?如何使用正则表达式匹配在模式数组中查找字符串?
【发布时间】:2026-02-19 04:25:02
【问题描述】:

假设我有一个字符串数组,例如@matches = ("cat", "zebra", "apple"),我想打开一个文件并尝试以最简单的方式匹配这些字符串。

while (<MYFILE>)
{
    chomp;

    if (..some match condition...)
    {
        ..stuff..
    }
}

我可以在每一行上使用foreach 来尝试匹配,但我知道在 Perl 中必须有一种简洁的方式来表示“如果字符串 X 匹配数组 Y 中的任何模式”。我似乎在任何地方都找不到这个。

编辑:

为了澄清,这是效率极低的代码:

while (<MYFILE>)
{
    chomp;

    foreach $m (@matches)
    { 
        if (~ /$m/)
        {
            ..stuff..
        }
    }
}

我知道有一些速记方法可以做到这一点。

【问题讨论】:

  • “匹配”是什么意思? (a)“等于”,(b)“包含为子字符串”,还是(c)“用作正则表达式时匹配”?你愿意使用非核心模块吗?这为any-junction 提供了一个很好的用例

标签: perl


【解决方案1】:

使用join 做一个即兴的正则表达式怎么样?

my @matches = ("cat", "zebra", "apple");
my $rx = join "|", @matches;

while (<$fh>) {
    if ($_ =~ /$rx/) {
         # stuff
    }
}

【讨论】:

  • 这很好,但首先,我认为只编译一次正则表达式会更有效,无论是使用qr 还是添加o 标志。其次,要注意交替中的单词顺序,因为cat|category可能很危险。
  • @Birei 您预见到catcategory 会发生冲突的字符串会有一些问题?
  • 我认为 OP 还想知道匹配的内容,而不仅仅是匹配是否存在。没问题,算了。
  • @Birei 那你可以my @words = /($rx)/g,顺序无所谓。
  • @Birei 哦,对了。是的,我想那会是更好的方法。虽然正确的方法可能是不允许cat 部分匹配category,例如使用单词边界。
【解决方案2】:

您似乎想将@matches 的条目用作正则表达式。然后,您可以将它们加入更大的正则表达式:

my $rx = join '|', @matches;

while (<>) {
  do stuff if $_ =~ $rx;
}

如果您想匹配 @matches 条目的文字内容,以便 @matches = ("foo+") 匹配行 foo+ 而不是 fooo 就像上面的解决方案一样,您可以构造正则表达式

my $rx = join '|', map quotemeta, @matches;

【讨论】:

    【解决方案3】:
    my @matches = qw( cat zebra apple );
    
    {   local $" = '|';
    
        while (<>) {
            chomp;
            if (/@matches/) { ... }
        }
    }
    

    但要小心。阅读文档:

    perldoc perlvar | grep "\$LIST_SEPARATOR" -A 12
    

    :)

    【讨论】:

      最近更新 更多