gpt4 book ai didi

regex - while() 中的全局正则表达式匹配反引号结果

转载 作者:行者123 更新时间:2023-12-03 15:01:13 24 4
gpt4 key购买 nike

此脚本搜索包含单词的行并打印它们,而 在每次迭代中重新读取源文件 :

# cat mm.pl
#!/usr/bin/perl
use strict;
use warnings;

while( `cat aa` =~ /(\w+)/g ) {
print "$1\n";
}

输入文件:
# cat aa
aa
bb
cc

结果:
# ./mm.pl
aa
bb
cc

请解释为什么运行脚本不是 无尽 .

正则表达式引擎的每一次迭代偏移 应该重置 因为表达式发生了变化(新猫被 fork 了)。

我认为 perl 对 cat 结果做了某种缓存,但 strace 声称 cat 被生成了 4 次(3 行 3 行 + 1 表示 false while 条件):
# strace -f ./mm.pl 2>&1 | grep cat | grep -v ENOENT
[pid 22604] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>
[pid 22605] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>
[pid 22606] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>
[pid 22607] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>

另一方面,以下示例 永远运行 :
# cat kk.pl
#!/usr/bin/perl
use strict;
use warnings;

my $d = 'aaa';
while( $d =~ /(\w+)/g ) {
print "$1\n";
$d = 'aaa';
}

这两个脚本之间的区别在哪里?我错过了什么?

最佳答案

//g所在的位置left off 存储在添加到执行匹配的标量的魔法中。

$ perl -MDevel::Peek -e'$_ = "abc"; Dump($_); /./g; Dump($_);'
SV = PV(0x32169a0) at 0x3253ee0
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x323bae0 "abc"\0
CUR = 3
LEN = 10
COW_REFCNT = 1
SV = PVMG(0x326c040) at 0x3253ee0
REFCNT = 1
FLAGS = (SMG,POK,IsCOW,pPOK)
IV = 0
NV = 0
PV = 0x323bae0 "abc"\0
CUR = 3
LEN = 10
COW_REFCNT = 2
MAGIC = 0x323d050
MG_VIRTUAL = &PL_vtbl_mglob
MG_TYPE = PERL_MAGIC_regex_global(g)
MG_FLAGS = 0x40
BYTES
MG_LEN = 1

这意味着在反引号示例中观察到的行为唯一可能的方式是,如果匹配运算符在四次评估时都与同一个标量匹配!这怎么可能?这是因为反引号是使用 TARG 的运算符之一。

创建标量相对昂贵,因为它需要最多三个内存分配!为了提高性能,一个名为 TARG 的标量与某些运算符的每个实例相关联。当对带有 TARG 的运算符求值时,它可能会用要返回的值填充 TARG 并返回 TARG(而不是分配并返回一个新值)。

“那又怎样?”,你可能会问。毕竟,您已经证明分配给标量会重置与该标量关联的匹配位置。这就是应该发生的事情,但它不适用于反引号。

Magic 不仅允许将信息附加到变量,它还附加在特定条件下要调用的函数。由 //g 添加的魔法附加一个应在修改标量后调用的函数(由上面转储中的 SMG 标志指示)。此函数用于在将值分配给标量时清除位置。

赋值运算符正确处理魔术,但不是由反引号运算符处理。它不希望魔法被添加到它的 TARG,所以它不检查是否有魔法,所以清除匹配位置的函数没有被调用。

关于regex - while() 中的全局正则表达式匹配反引号结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43257186/

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