我有这个Perl脚本:
use strict;
use warnings;
foreach my $line (" ^?[?12;12A", " ^?[A") {
print "$line\n";
$line =~ s/\s?[[:cntrl:]]\[(\?)?([0-9]{1,2}(;[0-9]{1,2})?)?[a-zA-Z]//g;
print "$line\n";
}
这是两个以空格开头的字符串,然后是控制字符,再然后是一些常规的ascii字符。
$ perl foo.pl
[?12;12A
Modification of a read-only value attempted at foo.pl line 6.
$
我做错了什么?
2条答案
按热度按时间r1wp621o1#
在foreach循环中,循环变量(“topicizer”)只是当前处理的列表元素的别名;通过改变它我们实际上改变了元素。
如果LIST的任何元素是左值,你可以通过修改循环中的VAR来修改它。相反,如果LIST的任何元素不是左值,任何修改该元素的尝试都将失败。换句话说,
foreach
循环索引变量是你正在循环的列表中每一项的隐式别名。问题中的循环遍历了一个 * 字符串常量 * 列表,这些都是只读的。试图改变它是一个致命错误(perldiag)(这个例子,
foreach
,作为一个例子给出)。Hameed's answer中显示了一些解决方法,将它们存储在数组中,或者首先将字符串文字赋给变量。
或者,在替换运算符
s///r
上使用“非破坏性”修饰符,它不会更改原始值,但会返回更改后的值(如果未更改,则返回原始值)eyh26e7m2#
在本例中,$line是只读值。
您可以通过两种方式解决此问题:
1.使用
my @testarray = (" ^?[?12;12A", " ^?[A");
之类的实际数组1.将$line的值赋给另一个变量并修改: