使用只有3位索引的列表元素进行正则表达式替换并不像我预期的那样工作

时间:2018-03-26 13:04:34

标签: regex perl

今天我遇到了a twitter post告诉我另一个神秘的Perl行为。有人可以告诉我以下脚本中的第3个语句有什么问题吗?我在perldoc中寻找文档的相关部分。

#!/usr/bin/perl

$x[1]    = "foo"; $_ = "foo"; s/$x[1]/bar/;    print "$_\n";
$x[10]   = "foo"; $_ = "foo"; s/$x[10]/bar/;   print "$_\n";
$x[100]  = "foo"; $_ = "foo"; s/$x[100]/bar/;  print "$_\n";
$x[1000] = "foo"; $_ = "foo"; s/$x[1000]/bar/; print "$_\n";

__END__
bar
bar
foo
bar

似乎perl解释器倾向于将$x[100]分开。

$x[100] = 'foo';
$_ = 'foo';
s/${x}[100]/bar/;
print "$_\n";

修改

谢谢大家。我在Camel Book中找到了一个文档,它建议 与@ fred-gannet完全相同。启发式的因素是数字 字符出现和括号中的修剪策略。

https://books.google.com/books?id=xx5JBSqcQzIC&lpg=PR1&pg=PA65#v=onepage&q&f=false

  

在搜索模式中,也进行双引号插值,   有一个不幸的含糊之处:/$foo[bar]/被插值为   /${foo}[bar]/(其中[bar]是正则表达式的字符类)   或者/${foo[bar]}/(其中[bar]是数组@foo的下标)?如果   @foo除此之外不存在,它显然是一个角色类。如果@foo   存在,Perl对[bar]进行了很好的猜测,并且几乎总是正确的。†如果   它确实猜错了,或者如果你只是普通的偏执,你可以强迫   如前所示,使用大括号进行正确插值。即使你只是   谨慎,这可能不是一个坏主意。

https://rt.perl.org/Public/Bug/Display.html?id=133027#txn-1542459

  

代码位于S_intuit_more()。

https://github.com/Perl/perl5/blob/823ba440369100de3f2693420a3887a645a57d28/toke.c#L4207-L4217

if (*s == '$')
    weight -= 3;
else if (isDIGIT(*s)) {
    if (s[1] != ']') {
    if (isDIGIT(s[1]) && s[2] == ']')
        weight -= 10;
    }
    else
    weight -= 100;
}
Zero(seen,256,char);

日语中有逻辑的解释。 (令人惊讶!)

https://8-p.info/perl-interpolation/

2 个答案:

答案 0 :(得分:5)

显然perl在数组索引和正则表达式字符集(例如/[a-z]/)之间感到困惑。行为不一致。 100至998的指数似乎受此影响。请使用脚本perlbug报告错误。

答案 1 :(得分:2)

当括号为

时,表达式会持续评估
s/${x[100]}/bar/;

索引为100..998时的解释不一致似乎有点像。