我想搜索文件的行以查看它们中的任何一个是否匹配一组正则表达式中的一个.
这样的事情:
my @regs = (qr/a/, qr/b/, qr/c/);
foreach my $line (<ARGV>) {
foreach my $reg (@regs) {
if ($line =~ /$reg/) {
printf("matched %s\n", $reg);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这可能很慢.
似乎正则表达式编译器可以提供帮助.有这样的优化:
my $master_reg = join("|", @regs); # this is wrong syntax. what's the right way?
foreach my $line (<ARGV>) {
$line =~ /$master_reg/;
my $matched = special_function();
printf("matched the %sth reg: %s\n", $matched, $regs[$matched]
}
Run Code Online (Sandbox Code Playgroud)
}
其中'special_function'是特殊的酱,告诉我正则表达式的哪一部分匹配.
使用捕获括号.基本思路如下:
my @matches = $foo =~ /(one)|(two)|(three)/;
defined $matches[0]
and print "Matched 'one'\n";
defined $matches[1]
and print "Matched 'two'\n";
defined $matches[2]
and print "Matched 'three'\n";
Run Code Online (Sandbox Code Playgroud)
添加捕获组:
"pear" =~ /(a)|(b)|(c)/;
if (defined $1) {
print "Matched a\n";
} elsif (defined $2) {
print "Matched b\n";
} elsif (defined $3) {
print "Matched c\n";
} else {
print "No match\n";
}
Run Code Online (Sandbox Code Playgroud)
显然,在这个简单的例子中,您可以使用/(a|b|c)/同样的方式并且只是打印$1,但是当'a','b'和'c'可以是任意复杂的表达式时,这是一个胜利.
如果你以编程方式构建正则表达式,你可能会发现必须使用带编号的变量很痛苦,所以不要破坏严格性,而是查看@-或者@+数组,其中包含每个匹配位置的偏移量.$-[0]只要模式匹配,总是设置,但$-[$n]如果n匹配的匹配组,则更高只包含定义的值.