Perl正则表达式的'o'修饰符是否仍然提供任何好处?

Jon*_*ler 38 regex perl

过去认为在Perl正则表达式的末尾包含'o'修饰符是有益的.目前的Perl文档似乎甚至没有列出它,当然也不是在perlre修饰符部分.

它现在提供任何好处吗?

仍然接受,因为如果没有别的向后兼容的原因.


正如JA Faucett和brian d foy所指出的那样,如果找到合适的位置(其中一个不是perlre文档),"o"修饰符仍然有记录.它在perlop页面中提到过.它也可以在perlreref页面中找到.

正如Alan M在接受的答案中所指出的,更好的现代技术通常是使用qr //(引用的正则表达式)运算符.

Ala*_*ore 37

我确信它仍然受到支持,但它已经过时了.如果你想要只编译一次正则表达式,你最好使用正则表达式对象,如下所示:

my $reg = qr/foo$bar/;
Run Code Online (Sandbox Code Playgroud)

插值$bar是在初始化变量时完成的,因此您将始终在封闭范围内使用缓存的,已编译的正则表达式.但有时您希望重新编译正则表达式,因为您希望它使用变量的新值.这是Friedl在The Book中使用的例子:

sub CheckLogfileForToday()
{
  my $today = (qw<Sun Mon Tue Wed Thu Fri Sat>)[(localtime)[6]];

  my $today_regex = qr/^$today:/i; # compiles once per function call

  while (<LOGFILE>) {
    if ($_ =~ $today_regex) {
      ...
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在函数范围内,$ today_regex的值保持不变.但是下次调用该函数时,将使用新值重新编译正则表达式$today.如果他刚刚使用过

if ($_ =~ m/^$today:/io)
Run Code Online (Sandbox Code Playgroud)

...正则表达式永远不会更新.因此,使用对象形式,您可以在不牺牲灵活性的情况下获得/ o的效率.


bri*_*foy 17

/o修改是在perlop中的文件,而不是perlre文档,因为它是一个报价般的修饰,而不是一个正则表达式修改.这对我来说似乎总是很奇怪,但事实就是如此.从Perl 5.20开始,它现在只是在perlre中列出,你可能不应该使用它.

在Perl 5.6之前,即使变量没有改变,Perl也会重新编译正则表达式.你不需要那样做了./o尽管对变量进行了进一步的更改,您可以使用一次编译正则表达式,但正如其他答案所指出的那样,qr//更好.


Rhu*_*arb 6

在Perl 5版本20.0文档 http://perldoc.perl.org/perlre.html中 说明

Modifiers

Other Modifiers

…

o - pretend to optimize your code, but actually introduce bugs
Run Code Online (Sandbox Code Playgroud)

这可能是一种幽默的说法,它应该执行某种优化,但实施却被打破了.

因此,最好避免使用该选项.

  • 技术背景是 m//o 在线程和非线程 perls 下的行为不同。使用线程 perls m/$foo/o 不会使用 $foo 的新值重新编译正则表达式,但没有线程它会。这通常被认为是一个错误。在 5.005_02 之前,您可以在编译时更改 $foo,但不能再在运行时更改,这更加一致 (OPpRUNTIME)。但这从来没有得到修复,所以现在 m/$foo/o 被认为是带有线程 perls 的错误。在 v5.26 中,OPpRUNTIME 标志被完全删除,而没有解释问题的背景。 (2认同)