Regex 如何在Perl中匹配多个正则表达式?
我想检查一些字符串是否与给定的正则表达式集匹配。我该怎么做呢?我不太确定你在找什么,但类似的东西Regex 如何在Perl中匹配多个正则表达式?,regex,perl,Regex,Perl,我想检查一些字符串是否与给定的正则表达式集匹配。我该怎么做呢?我不太确定你在找什么,但类似的东西 #!/usr/bin/perl @regexes = ( qr/foo/ , qr/bar/ ); while ($line=<>){ chomp $line; $match=0; for $re (@regexes){ $match++ if ($line =~ $re); } print "$line matches $match regexes\n";
#!/usr/bin/perl
@regexes = ( qr/foo/ , qr/bar/ );
while ($line=<>){
chomp $line;
$match=0;
for $re (@regexes){
$match++ if ($line =~ $re);
}
print "$line matches $match regexes\n";
}
#/usr/bin/perl
@正则表达式=(qr/foo/,qr/bar/);
而($line=){
chomp$行;
$match=0;
$re(@regexes){
$match++if($line=~$re);
}
打印“$line matches$match regex\n”;
}
您也可以将它们编译成一个单独的正则表达式,如下所示:
#!/usr/bin/perl
@regexes = ( qr/foo/ , qr/bar/ );
$allre= "(".join("|",@regexes).")";
$compiled=qr/$allre/;
while(<>){
chomp;
print "$_ matches ($1)\n" if /$compiled/;
}
#/usr/bin/perl
@正则表达式=(qr/foo/,qr/bar/);
$allre=“”(“.join(|)”,@regexes)。”;
$compiled=qr/$allre/;
while(){
咀嚼;
如果/$compiled/,则打印“$\匹配($1)\n”;
}
希望对您有所帮助。如果您使用的是perl 5.10或更高版本,请使用智能匹配
#! /usr/bin/env perl
use warnings;
use strict;
use feature 'switch';
my @patterns = (
qr/foo/,
qr/bar/,
qr/baz/,
);
for (qw/ blurfl bar quux foo baz /) {
no warnings 'experimental::smartmatch';
print "$_: ";
given ($_) {
when (@patterns) {
print "hit!\n";
}
default {
print "miss.\n";
}
}
}
虽然您没有看到显式的~
操作符,但它是否在幕后:
大部分功能来自于有时可以应用的隐式智能匹配。大多数情况下,当(EXPR)
被视为$\u
的隐式智能匹配时,也就是说,$\uexpr
。(有关smartmatching的更多信息,请参阅。)
给出了一个可以使用的多种组合的表,上面的代码对应于$a
是Any而$b
是Array的情况,大致对应于
grep $a ~~ $_, @$b
除了搜索短路,即在匹配时快速返回,而不是处理所有元素。在隐式循环中,我们聪明地将Any与Regex匹配,这是
$a =~ /$b/
输出:
blurfl: miss.
bar: hit!
quux: miss.
foo: hit!
baz: hit!
小姐。
酒吧:击中!
库克斯:小姐。
福:击中!
巴兹:击中!
补遗 由于这个答案最初是编写的,Perl的设计人员已经意识到smartmatching的工作方式存在错误,事实就是如此。上面使用的案例不是有争议的用途之一,尽管如此,代码的输出将包括
给定的是实验性的
和何时是实验性的
,除了我添加了无警告“实验::smartmatch”代码>
任何实验特性的使用都有一定的风险,但我估计这种情况发生的可能性很低。当使用与上述类似的代码并升级到较新版本的Perl时,这是一个需要注意的潜在问题。From的答案,在本例中,是我刚刚用智能匹配示例更新的最新开发版本
如何一次有效地匹配多个正则表达式
(布莱恩·福伊撰稿)
如果您有Perl5.10或更高版本,这几乎是微不足道的。你真聪明
匹配正则表达式对象数组:
my @patterns = ( qr/Fr.d/, qr/B.rn.y/, qr/W.lm./ );
if( $string ~~ @patterns ) {
...
};
智能匹配在找到匹配项时停止,因此不必尝试
每个表情
在Perl5.10之前,您还有一些工作要做。你想
避免每次要匹配正则表达式时都编译它。
在本例中,perl必须为每个
C循环的迭代,因为它无法知道
C将是:
my @patterns = qw( foo bar baz );
LINE: while( <DATA> ) {
foreach $pattern ( @patterns ) {
if( /\b$pattern\b/i ) {
print;
next LINE;
}
}
}
my@patterns=qw(foo-bar-baz);
行:while(){
foreach$pattern(@patterns){
如果(/\b$pattern\b/i){
印刷品;
下一行;
}
}
}
C操作符出现在perl 5.005中。它编写了一个常规的
表达式,但不应用它。当您使用预编译的
在正则表达式的版本中,perl做的工作更少。在本例中,我插入了
C将每个模式转换为其预编译形式。其余的
脚本相同,但速度更快:
my @patterns = map { qr/\b$_\b/i } qw( foo bar baz );
LINE: while( <> ) {
foreach $pattern ( @patterns ) {
if( /$pattern/ )
{
print;
next LINE;
}
}
}
my@patterns=map{qr/\b$\b/i}qw(foo-bar-baz);
行:while(){
foreach$pattern(@patterns){
如果(/$pattern/)
{
印刷品;
下一行;
}
}
}
在某些情况下,您可以将多个模式制作成一个单独的模式
正则表达式。注意需要回溯的情况
不过
my$regex=join'|',qw(foo-bar-baz);
行:while(){
如果打印/\b(?:$regex)\b/i;
}
有关正则表达式效率的更多详细信息,请参阅Jeffrey Freidl的I。他解释说有多规律
表达式引擎工作以及为什么某些模式令人惊讶
效率低下。一旦您了解了perl如何应用正则表达式,
您可以针对具体情况对它们进行调优。如果使用大量regexp,您可能会感兴趣
请参见概要部分:
use Regexp::Optimizer;
my $o = Regexp::Optimizer->new;
my $re = $o->optimize(qr/foobar|fooxar|foozap/);
# $re is now qr/foo(?:[bx]ar|zap)/
如果你愿意安装一个额外的模块,这可能会更有效。我一次针对多个正则表达式测试一个值的方法是,它将“将多个正则表达式组装成一个re”,比简单地执行连接“|”和@regexps
的方式更智能和优化。默认情况下,您还可以检索匹配的文本部分,如果您需要知道匹配的模式,则track
开关将提供该信息。它的性能相当好——在一个应用程序中,我用它一次测试1700个模式——而且我还需要它做不到的任何事情。您必须迭代它们,看看它们是否有match@brian我并没有说你必须重复所有这些,智能匹配非常酷。我从没想过要做那样的事。今天晚些时候,我将在FAQ中添加一个类似的示例。:)+1谢谢!只有一件小事:知道有一个匹配对我来说就足够了,这样我可以在找到第一个匹配后立即停止,而不要试图根据剩余的模式寻找匹配。我怎样才能修改你的代码来做到这一点呢?@David B智能匹配中的隐式循环已经在找到匹配项后停止(“短路”)。你的意思是在“blurfl”
、“bar”
和朋友之间的外环吗?如果是,请在when
块中使用last
。另请参阅:该发行版中默认未安装的命令行工具,以及改进的。
use Regexp::Optimizer;
my $o = Regexp::Optimizer->new;
my $re = $o->optimize(qr/foobar|fooxar|foozap/);
# $re is now qr/foo(?:[bx]ar|zap)/