我已经在Perl中编程了多年,现在已经很多年了,尽管它偶尔只是我的主要语言。因为我经常在几个月没有写任何perl,所以我非常依赖我的狗耳骆驼书来提醒我如何做事。然而,当我逐字逐句地复制食谱时,这让我感到困扰。这是最令人头疼的问题之一:在第3版Camel的第154页上,有一个“修改字符串 en passant 的示例,其内容如下:
($lotr = $hobbit) =~ s/Bilbo/Frodo/g;
Q1)这里发生了什么?究竟什么是正则表达式运作?
Q2)这种基本操作是否需要这种近乎神奇的语法,如“从$ a中取一个字符串,用正则表达式修改它,将结果放在$ b中”?
Q3)如何使用循环默认变量作为初始字符串来执行此操作?
向Perl梦想家道歉,上面看起来非常自然。
答案 0 :(得分:22)
嗯...... ($lotr=$hobbit) =~ s/Bilbo/Frodo/g
是Perl众多魔法师之一。现在回答一些问题。
Q1)$lotr
被分配$hobbit
中包含的值。在赋值之后,我们可以忘记源变量。如果我们写了:
($lotr = $hobbit)
视为自己的陈述
$lotr = $hobbit;
$lotr =~ s/Bilbo/Frodo/g;
代替。正则表达式在$lotr
上运行。
Q2)语法只是上面给出的片段的一行版本。可以将其视为“从$a
复制字符串,将其复制到$b
,然后使用正则表达式修改$b
”而不是“从$a
获取字符串,修改它使用正则表达式,将结果放在$b
“
Q3)我假设您的意思是“循环默认变量”的默认模式搜索空间?在这种情况下,只需使用$_
代替$hobbit
:
while (<>) {
chomp;
($lotr = $_) =~ s/Bilbo/Frodo/g;
print "\$lotr = [$lotr]\n";
print "\$_ = [$_]\n";
}
有趣的是,此操作不会修改magic var $_
。这就是你如何得出结论在正则表达式替换之前发生并且替换不会以任何方式在默认模式空间上进行交互的结果。
对于经验丰富的Perl程序员来说......我不知道有多少人被Perl语法所抛出,无论他们盯着它多长时间“当然是施瓦茨先生;” / p>
答案 1 :(得分:5)
不同的语言使用赋值运算符执行不同的操作。在某些情况下,它是一个语句,而不是表达式,因此不能组合成一个更大的表达式。在某些情况下,它返回指定的值,但仅作为值(通常称为rvalue),而不是可以修改或分配的值(左值)。一个例子是C,你在哪里 可写:
a = b = c; # assign value of c to b and a
但不是:
++(b = a); # assign value of a to b, then increment b
在某些情况下,赋值的结果是分配给的左值。 (在Perl中,这仅适用于标量赋值;列表赋值是一个更复杂的野兽。)所以你可以做++($ b = $ a)或($ b = $ a)= ~s / a / b /或任何其他期望赋值左值的操作,它将首先进行赋值,然后进一步修改赋值的左值。
答案 2 :(得分:1)
如果在Q2中你的意思是从$ a中取一个子串,你可能会觉得这个习惯用法很有用:
($b) = $a =~ /(substring-to-match)/;
$b =~ s/regex-on-susbtring/result-string/;
另请注意,$ a和$ b不是Perl中的常规变量,因为它们具有与sort函数相关的特殊范围规则。有关详细信息,请参阅'perldoc perlvar'。