gpt4 book ai didi

Perl 匹配变量和性能。它是如何工作的?

转载 作者:行者123 更新时间:2023-12-03 18:33:37 25 4
gpt4 key购买 nike

根据 perlvar :

Variables related to regular expressions

These variables are read-only and dynamically-scoped, unless we note otherwise. The dynamic nature of the regular expression variables means that their value is limited to the block that they are in.



再往下:

Traditionally in Perl, any use of any of the three variables $` , $& or $' anywhere in the code, caused all subsequent successful pattern matches to make a copy of the matched string, in case the code might subsequently access one of those variables.



在阅读了文档中的其余部分后,我仍然错过了一些信息,例如:
  • 为什么首先要复制?

    我想我知道这个问题的答案:从最后一个声明 "in case the code might subsequently access one of those variables" 中可以清楚地看出这一点。 .
    所以在我的理解中:
    my $s = "Hello world";
    $s =~ s/Hello //;
    say $';

    这仍然会打印 world因为之前复制了一份 $s被修改。
  • 为什么要复制整个字符串?

    在前面的例子中,只复制字符串的尾部就足够了,因为只有 $'被使用(我们没有使用 $`$& )。那么为什么要复制整个字符串呢?
  • 最后:既然它说 "all subsequent"而不是 "all subsequent matches in that block" ,我想确认一下:
    my $s = "no\n yesHello world";
    {
    $s =~ /yes/ and say $'; # Note the use of $'
    }
    $s = '12' x 1_000_000;
    my $n = () = $s =~ /2/g;
    say "Found $n matches";

    在这种情况下,(因为 $' 仅用于内部作用域)不会有与 $s =~ /2/g 中的一百万次成功匹配相关的复制。 ? (假设我没有在外部范围中提及 $`$&$' 中的任何一个)


  • 备注 :
  • 该问题假设 perl 版本低于 5.18。
    根据 perlvar :

    In Perl 5.18.0 onwards, perl started noting the presence of each of the three variables separately, and only copied that part of the string required

    In Perl 5.20.0 a new copy-on-write system was enabled by default, which finally fixes all performance issues with these three variables, and makes them safe to use anywhere.

  • 我只是出于好奇才问这个问题。我不打算在我的代码中实际使用这些变量中的任何一个,因为我希望我的程序也能有效地用于早期的 perl 版本(<5.20)。

    此外,如手册中所述,它们可以使用 $+[0] 轻松模拟(没有隐式复制和性能影响)。和 $-[0] (这是在 perl 5.6 版中引入的。我自己使用的是 perl 5.22 版)。见 perlvar想要查询更多的信息。
  • 最佳答案

  • 它必须复制字符串,因为原始变量可能已在正则表达式匹配和使用匹配变量的时间之间被修改:
    my $var = "foobar";
    $var =~ /.../ or die;
    $var = "hello";
    print "$& $'"; # outputs "foo bar"
  • 它必须有效地复制整个字符串,因为这就是 $` . $& . $'结果。正如您引用自己的那样,在 perl 5.18 中,有人意识到您可以单独跟踪每个变量,因此仅复制匹配之前的部分(或匹配本身,或匹配之后的部分),前提是该变量仅出现在代码中:

    In Perl 5.18.0 onwards, perl started noting the presence of each of the three variables separately, and only copied that part of the string required

  • 匹配变量是全局的。您可以随时调用访问 $` 的函数(调用调用函数的函数...)或 $&$' ,所以如果在代码中的任何地方看到这些变量,perl 必须在每次成功的正则表达式匹配后做一个完整的副本。 (基本上,perl 无法静态确定特定代码段永远不会访问这些匹配变量,从而避免复制。)
  • 关于Perl 匹配变量和性能。它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37633699/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com