多年来,我一直在Perl中编程,不过几年,虽然只是偶尔使用它是我的主要语言.因为我经常在几个月没有写任何perl,所以我非常依赖我的狗耳骆驼书来提醒我如何做事.然而,当我逐字逐句地复制食谱时,这让我感到困扰.这是最令人头疼的问题之一:在第3版Camel的第154页,有一个"修改字符串en passant的例子,其内容如下:
($lotr = $hobbit) =~ s/Bilbo/Frodo/g;
Q1)这里发生了什么?究竟什么是正则表达式运作?
Q2)这种近乎神奇的语法是否需要这样的基本操作:"从$ a中取一个字符串,用正则表达式修改它,将结果放在$ b中"?
Q3)如何使用循环默认变量作为初始字符串来执行此操作?
向Perl梦想家道歉,上面看起来非常自然.
嗯... ($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语法所抛出,无论他们多久盯着它,"当然是施瓦茨先生;"
不同的语言使用赋值运算符执行不同的操作.在某些情况下,它是一个语句,而不是表达式,因此不能组合成一个更大的表达式.在某些情况下,它返回指定的值,但仅作为值(通常称为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 /或任何其他期望赋值左值的操作,它将首先进行赋值,然后进一步修改赋值的左值.