【问题标题】:Metaquoting patterns in a variable list变量列表中的元引用模式
【发布时间】:2012-04-21 10:40:12
【问题描述】:

我有一个要在字符串中查找的模式列表。这些模式很多,并且包含许多我只想按字面匹配的元字符。所以这是使用\Q..\E 进行元引用的完美应用程序。复杂之处在于我需要将模式的变量列表加入到正则表达式中。

use strict;
use warnings;
# sample string to represent my problem
    my $string = "{{a|!}} Abra\n{{b|!!}} {{b}} Hocus {{s|?}} Kedabra\n{{b|+?}} {{b|??}} Pocus\n {{s|?}}Alakazam\n";

# sample patterns to look for    
my @patterns = qw({{a|!}} {{s|?}} {{s|+?}} {{b|?}});
# since these patterns can be anything, I join the resulting array into a variable-length regex
my $regex = join("|",@patterns);

my @matched = $string =~ /$regex(\s\w+\s)/; # Error in matching regex due to unquoted metacharacters
print join("", @matched); # intended result: Hocus\n Pocus\n

当我尝试在加入操作中引入元引用时,它们似乎没有任何效果。

# quote all patterns so that they match literally, but make sure the alternating metacharacter works as intended
my $qmregex = "\Q".join("\E|\Q", @patterns)."\E";

my @matched = $string =~ /$qmregex(\s\w+\s)/; # The same error

由于某种原因,当元引用包含在我用作正则表达式的字符串中时,它不起作用。对我来说,它们只有在像/\Q$anexpression\E/ 那样直接添加到正则表达式时才起作用,但据我所知,这对我来说不是一个选择。我该如何解决这个问题?

【问题讨论】:

    标签: regex perl escaping metacharacters


    【解决方案1】:

    我不明白您的预期结果,因为 AbraKedabra 是唯一以任何模式开头的字符串。

    要解决您的问题,您必须分别转义正则表达式的每个组件,因为 \Q\E 仅影响它们出现的字符串的值,因此 "\Q""\E" 只是空字符串 @ 987654327@ 和 "\E|\Q" 只是 "|"。你可以写

    my $qmregex = join '|', map "\Q$_\E", @patterns;
    

    但调用quotemeta函数更简单。

    您还必须将列表括在括号 (?:...) 中以隔离交替,并将 /g 修饰符应用于正则表达式匹配以查找字符串中的所有匹配项。

    试试

    use strict;
    use warnings;
    
    my $string = "{{a|!}} Abra\n{{b|!!}} {{b}} Hocus {{s|?}} Kedabra\n{{b|+?}} {{b|??}} Pocus\n {{s|?}}Alakazam\n";
    
    my @patterns = qw(  {{a|!}} {{s|?}} {{s|+?}} {{b|?}}  );
    
    my $regex = join '|', map quotemeta, @patterns;
    my @matched = $string =~ /(?:$regex)(\s\w+\s)/g;
    print @matched;
    

    输出

     Abra
     Kedabra
    

    【讨论】:

      猜你喜欢
      • 2015-11-08
      • 2022-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-13
      • 1970-01-01
      相关资源
      最近更新 更多