在正则表达式中使```条件有限制吗?

时间:2016-12-28 09:01:56

标签: regex perl

我有以下代码

$regex_data = "pattern|pattern1|pattern2|pattern3|pattern4|pattern5|pattern6";  

my $data = "This line has some pattern";

if($data=~m/$regex_data/i)
{
    print "Data matched with pattern\n";
}

在上面的代码$regex_data中,所有可能的模式都由|分隔。我正在处理未来的项目,然后我不知道模式的限制。所以$regex_data直接实现了正则表达式匹配。现在它正在工作(对于一小组模式1..100)。我怀疑在正则表达式的大型模式中是否会出现任何问题。

$regex_data = "pattern1|pattern2|pattern3|pattern4|pattern5|pattern6|pattern7|pattern8|pattern9|pattern10|pattern11|pattern12|pattern13|pattern14|pattern15|pattern16|pattern17|pattern18|pattern19|pattern20|pattern21|pattern22|pattern23|pattern24|pattern25|pattern26|pattern27|pattern28|pattern29|pattern30 .. and so on ";

3 个答案:

答案 0 :(得分:4)

正如我在评论中所写,对交替长度的唯一实际限制是它占用的内存量

正则表达式引擎将交替编译成 trie 结构,我猜想将字符串扩展为备选列表会比编译的正则表达式占用更多内存< / p>

另一方面,Perl循环的替代方案存在很大的速度劣势

  • trie 算法比简单的迭代比较快得多

  • 正则表达式引擎是用C语言编写的,通常比Perl代码快得多

  • Perl循环必须对列表的每个段执行单独的正则表达式编译

这是一个简单的基准测试,您可能希望将其扩展为更具代表性的数据集。直接使用交替作为正则表达式可以快2.5倍

use strict;
use warnings 'all';

use Benchmark 'cmpthese';
use List::Util 'any';

my $regex_data = 'pattern|pattern1|pattern2|pattern3|pattern4|pattern5|pattern6';

my $re = qr/$regex_data/i;

my $data = "This line has some pattern";

cmpthese(-10,{
    loop  => sub { any { $data =~ /$_/ } split /\|/, $regex_data },
    regex => sub { $data =~ $re },
});

输出

          Rate  loop regex
loop  134375/s    --  -60%
regex 338449/s  152%    --

答案 1 :(得分:0)

如果未知限制意味着未知数量的更改,您可以使用qr运算符一次添加一个。如果@patterns包含备选列表:

use Data::Dumper;
my $re = qr{ \Q$patterns[0]\E }x;
for ( @patterns[1..$#patterns] ){
    $re = qr{ $re | \Q$_\E }x;
}
say Dumper $re;

有关详细信息,请参阅perldoc -f qr

答案 2 :(得分:-2)

您可以使用数组列表

use strict;
use warnings;

my $regex_data = "pattern|pattern1|pattern2|pattern3|pattern4|pattern5|pattern6";  

my @arrays = split/\|/, $regex_data;
my $data = "This line has some pattern";
if (grep { $data=~ /\b$_\b/} @arrays) 
{
    print "Data matched with pattern\n";
}
else
{
    print "Not matched...\n";
}