我有一个要在字符串中查找的模式列表。这些模式数不胜数,包含许多元字符,我只想从字面上匹配它们。所以这是使用\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/中那样直接添加到正则表达式中时,它们才能工作,但据我所知,这不是我的选择。我该如何解决这个问题呢?
发布于 2012-04-09 06:33:56
我不理解您所期望的结果,因为Abra和Kedabra是所有模式前面唯一的字符串。
要解决您的问题,您必须单独转义正则表达式的每个组件,因为\Q和\E只影响出现它们的字符串的值,所以"\Q"和"\E"只是空字符串"",而"\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
Kedabrahttps://stackoverflow.com/questions/10066746
复制相似问题