gpt4 book ai didi

regex - 为什么 Perl 的 m//g 运算符有时会导致在文本中引入 NULL?

转载 作者:行者123 更新时间:2023-12-01 08:16:59 24 4
gpt4 key购买 nike

我们最近在我们的一个 Perl 脚本中遇到了一些奇怪的结果,其中在某些文本中引入了 NULL 字符(Pe​​rl 中的\0)。我们最终将其追踪到偶然在 Perl m//匹配运算符上使用的//g 运算符。在这发生之前,我什至不知道您可以将//g 与 m//运算符一起使用,因为我只将它与 s///运算符一起使用。

无论如何,即使我们通过删除错误的//g 修复了错误,我还是很想知道为什么这个小脚本会在文本中引入一个 NULL 字符! :-)

my $text = "01";

if ($text =~ m/(\d+)/g)
{
$text = "A$1";
}

if ($text =~ m/\0/)
{
print "Text contains NULL!\n";
}

防止 NULL 出现的细微变化:如果我更改 $text 的值(例如仅更改为“0”或仅更改为“1”或许多其他组合),则不再引入 NULL。如果我将分配值从“A$1”更改为“$1”,则不再引入 NULL。如果我将“A$1”分配给一个完全不同的变量,则不会在该变量中引入 NULL。如果我在 m//匹配期间删除//g 运算符,则不会引入 NULL。

Perl 大师可以解释这种行为吗?我通过谷歌搜索找不到任何东西。

最佳答案

if ($text =~ m/(\d+)/g)

是错的。具体来说,形式的代码 if (/.../g)是错的。它在概念上没有任何意义(“如果匹配直到不匹配”???)并且会产生不想要的结果。
$_ = "01ab";
if (/(\d+)/g) { say $1; } # 01
if (/(.*)/g) { say $1; } # ab!!!

摆脱“g”。

字符串的结尾通常后跟一个 NUL。
$ perl -MDevel::Peek -e'Dump "01"'
SV = PV(0x88b4740) at 0x88d1368
REFCNT = 1
FLAGS = (PADTMP,POK,READONLY,pPOK)
PV = 0x88d52f0 "01"\0
CUR = 2
LEN = 12

您的 Perl 版本似乎有一个错误,当匹配的起始位置位于字符串的末尾时,它会匹配该 NUL。没有插入 NUL。幸运的是,如果您修复了有问题的代码,您就不会遭受此错误的困扰。
../perl/Porting/bisect.pl           \
--target=miniperl --expect-fail \
--start=v5.13.0 --end=v5.14.0 \
-e'
my $text = "01";
if ($text =~ m/(\d+)/g) { $text = "A$1"; }
exit($text =~ m/\0/ ? 1 : 0);
'

显示它是由 6f1401dc2acd2a2b85df22b0a74e5f7e6e0a33aa 修复的.

基于 git tag --contains 6f1401dc2acd2a2b85df22b0a74e5f7e6e0a33aa , 5.13.2 是第一个开发版本,5.14.0 是第一个有修复的生产版本。

关于regex - 为什么 Perl 的 m//g 运算符有时会导致在文本中引入 NULL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8672911/

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