Есть ошибка perl
, но у вас также есть проблема с программированием.Не полагайтесь на значение специальных переменных, за исключением немедленного выражения после их установки.Сохраните их значения сразу.
Когда вы столкнетесь с такими проблемами, посмотрите на данные.Это оказывается странным, который выглядит как ошибка с обработкой буферов захвата.
use v5.10;
use feature qw(unicode_strings);
my $text = "01";
if ($text =~ m/(\d+)/g)
{
say "\$1 [$1]: ", join ' ', map { sprintf '%04X', ord } split //, $1;
say 'Text: ', join ' ', map { sprintf '%04X', ord } split //, $text;
$text = "A$1";
say "\$1 [$1]: ", join ' ', map { sprintf '%04X', ord } split //, $1;
say 'Text: ', join ' ', map { sprintf '%04X', ord } split //, $text;
}
Все выглядит правильно, пока вы на самом деле не захотите использовать $1
для построения новой строки для присвоения той же переменной, в этот момент значение, по-видимому, исчезает.Обратите внимание, что после назначения $1
отличается:
% perl5.12.2 test.pl
$1 [01]: 0030 0031
Text: 0030 0031
$1 [AA]: 0041 0041
Text: 0041 0041 0000
Это тоже странным образом отличается.perl
делает некоторую хитрую обработку, чтобы запомнить смещения в строке.В v5.14 $1
по-прежнему первые два символа в строке:
% perl5.14.2 test.pl
$1 [01]: 0030 0031
Text: 0030 0031
$1 [A0]: 0041 0030
Text: 0041 0030 0031
Эта проблема не возникает, если вы назначаете новую переменную вместо использования $test
и $1
в том же утверждении (что должно быть совершенно нормально, но мы все знаем, что часто означает «должно быть»).Это также не проблема, если вы сразу фиксируете значение специальной переменной:
use v5.10;
use feature qw(unicode_strings);
my $text = "01";
if ($text =~ m/(\d+)/g)
{
my $one = $1;
say "\$1 [$1]: ", join ' ', map { sprintf '%04X', ord } split //, $1;
say 'Text: ', join ' ', map { sprintf '%04X', ord } split //, $text;
$text = "A$one";
say "\$1 [$1]: ", join ' ', map { sprintf '%04X', ord } split //, $1;
say 'Text: ', join ' ', map { sprintf '%04X', ord } split //, $text;
}
Теперь, даже v5.12 делает это правильно:
$ perl5.12.2 test.pl
$1 [01]: 0030 0031
Text: 0030 0031
$1 [A0]: 0041 0030
Text: 0041 0030 0031