Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 有没有办法在Perl中预编译正则表达式?_Regex_Perl_Compilation - Fatal编程技术网

Regex 有没有办法在Perl中预编译正则表达式?

Regex 有没有办法在Perl中预编译正则表达式?,regex,perl,compilation,Regex,Perl,Compilation,有没有办法在Perl中预编译正则表达式?我有一个在一个程序中多次使用的,并且在使用之间不会改变。使用qr//操作符(记录在下) 对于文本(静态)正则表达式,没有什么可做的——Perl只编译它们一次 if ($var =~ /foo|bar/) { # ... } 对于存储在变量中的正则表达式,您有两个选项。您可以使用运算符生成正则表达式对象: my $re = qr/foo|bar/; if ($var =~ $re) { # ... } 如果您想在多个位置使用正则表达式或

有没有办法在Perl中预编译正则表达式?我有一个在一个程序中多次使用的,并且在使用之间不会改变。

使用qr//操作符(记录在下)

对于文本(静态)正则表达式,没有什么可做的——Perl只编译它们一次

if ($var =~ /foo|bar/) {
    # ...
}
对于存储在变量中的正则表达式,您有两个选项。您可以使用运算符生成正则表达式对象:

my $re = qr/foo|bar/;

if ($var =~ $re) {
    # ...
}
如果您想在多个位置使用正则表达式或将其传递给子例程,这非常方便

如果正则表达式模式是一个字符串,则可以使用
/o
选项向Perl保证它永远不会更改:

my $pattern = 'foo|bar';

if ($var =~ /$pattern/o) {
    # ...
}

不过,通常最好不要这样做。Perl非常聪明,知道变量没有改变,并且不需要重新编译正则表达式。指定
/o
可能是过早的微观优化。这也是一个潜在的陷阱。如果使用
/o
更改了变量,则无论如何都会导致Perl使用旧的正则表达式。这可能会导致难以诊断的bug。

为了澄清,您可以将预编译的正则表达式用作:

my $re = qr/foo|bar/;  # Precompile phase
if ( $string =~ $re ) ...   # For direct use
if ( $string =~ /$re/ ) .... # The same as above, but a bit complicated
if ( $string =~ m/something $re other/x ) ...  # For use precompiled as a part of a bigger regex
if ( $string =~ s/$re/replacement/ ) ...  # For direct use as replace
if ( $string =~ s/some $re other/replacement/x ) ... # For use precompiled as a part of bigger regex, and as replace all at once

这在中有记录,但没有直接的例子。

这些都是正确的;然而,qr//已经支持了很多年了(它从5.005开始就存在,我认为从5.8开始就没有问题了)@ephemient好吧,5.10有一个与qr/(以及编译正则表达式)相关的严重内存泄漏,但这已经得到了修复。如果您使用的是5.10,那么可以通过说perl-e'qr//while 1'来检查是否存在内存泄漏。我知道ActiveState Perl 5.10的OS X版本仍处于崩溃状态。注意:2016年以来,
/o
修饰符已被弃用。有关详细信息,请参阅。对于使用相同预编译regexp的多个文件,可以多次使用my$re=qr/foo | bar/然后使用next if($var=~/something$re something/)。perlreI中记录了这一点,建议始终测量速度结果。永远不要相信“预编译的东西应该更快”的感觉。对我来说,在perl 5.24.1中,使用
qr/
而不是仅仅在代码中使用regexps内联,使速度降低了60%以上!很好,它似乎可以用作s///构造中的模式。在这种情况下,它仍然是预编译的还是再次编译的?@akostadinov它仍然是预编译的。我不认为“使用预编译作为更大的正则表达式的一部分”是正确的。正则表达式不能由字符串组成。如果在代码> > $Re>代码下的下一个字符是“代码> +/CODE”,那么考虑应该发生什么,它依赖于用于ReGEXP的实现和标志。只有做一些基准测试和测试才能告诉我们编译器真正的功能。当几乎不编译regexp时,更改$re值将不会产生任何效果。将使用旧的$re值。对于更一般的替换情况,请使用包含正则表达式和替换的变量(例如,
s/(\w+/\u\L$1/g;
(在变量/外部数据中),而不仅仅是变量中的固定字符串),请参阅
my $re = qr/foo|bar/;  # Precompile phase
if ( $string =~ $re ) ...   # For direct use
if ( $string =~ /$re/ ) .... # The same as above, but a bit complicated
if ( $string =~ m/something $re other/x ) ...  # For use precompiled as a part of a bigger regex
if ( $string =~ s/$re/replacement/ ) ...  # For direct use as replace
if ( $string =~ s/some $re other/replacement/x ) ... # For use precompiled as a part of bigger regex, and as replace all at once