Perl 替换运算符的作用是什么?

发布于 2024-07-10 02:19:03 字数 458 浏览 7 评论 0原文

多年来,我一直断断续续地使用 Perl 进行编程,尽管只是偶尔它是我的主要语言。 因为我经常几个月不写任何 Perl,所以我严重依赖我的卷角骆驼书来提醒我如何做事。 然而,当我在不理解的情况下逐字复制食谱时,这让我很烦恼。 这是最令人烦恼的问题之一:在第 3 版 Camel 的第 154 页上,有一个“修改字符串en passant”的示例,其内容如下:

($lotr = $hobbit) =~ s/Bilbo/Frodo/g;

Q1)这里发生了什么?关于什么确切地说,正则表达式正在运行吗?

Q2)这种近乎神奇的语法对于“从 $a 中获取字符串,用正则表达式修改它,将结果放入 $b”这样的基本操作是必要的吗?

Q3)我该怎么做 ?这个操作使用循环默认变量作为初始字符串?

提前向 Perl 梦想家致歉,对于他们来说,上面的内容看起来非常自然。

I have been programming in Perl, off and on, for years now, although only sporadically is it my primary language. Because I often go months without writing any perl, I rely heavily on my dog-eared Camel Book to remind me how to do things. However, when I copy recipes verbatim with no understanding, this bothers me. This is one of the most vexing: On page 154 of the 3rd edition Camel, there is an example for "modifying strings en passant, which reads like this:

($lotr = $hobbit) =~ s/Bilbo/Frodo/g;

Q1) what is going on here? On what, exactly, is the regex operating?

Q2) Is this near-magical syntax necessary for such a basic operation as "take a string from $a, modify it with a regex, place result in $b"?

Q3) How do I do this operation using the loop default variable as the initial string?

Apologies in advance to Perl dreamers for whom the above looks perfectly natural.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

卸妝后依然美 2024-07-17 02:19:03

嗯... ($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";
}

有趣的是,魔术变量 $_ 不会被此操作修改。 通过这种方式,您可以得出这样的结论:赋值发生在正则表达式替换之前,并且替换不会以任何方式与默认模式空间交互。

对于经验丰富的 Perl 程序员来说……我不知道有多少人会被某些 Perl 语法所困扰,无论他们已经盯着它看了多久,当然除了 Schwartz 先生;)

Hmmm... ($lotr=$hobbit) =~ s/Bilbo/Frodo/g is one of the many magicks of Perl. Now for some answers.

Q1) $lotr is being assigned the value contained in $hobbit. After the assignment, we can forget about the source variable. Treat ($lotr = $hobbit) as it's own statement as-if we had written:

$lotr = $hobbit;
$lotr =~ s/Bilbo/Frodo/g;

instead. The regex is operating on $lotr.

Q2) The syntax is simply a one-line version of the snippet given above. Think of it as "copy the string from $a, copy it into $b, and modify $b with the regex" instead of "take a string from $a, modify it with a regex, place result in $b"

Q3) I'm assuming that you mean the default pattern searching space by "loop default variable"? In that case, just use $_ instead of $hobbit:

while (<>) {
  chomp;
  ($lotr = $_) =~ s/Bilbo/Frodo/g;
  print "\$lotr = [$lotr]\n";
  print "\$_    = [$_]\n";
}

Interestingly enough, the magic var $_ is not modified by this operation. This is how you can conclude that the assignment happens before the regex substitution and that the substitution does not interact on the default pattern space in any way.

And for the experienced Perl programmers thing... I don't know too many people that are thrown by some piece of Perl syntax regardless of how long they have been staring at it 'cept Mr. Schwartz of course ;)

指尖上得阳光 2024-07-17 02:19:03

不同的语言使用赋值运算符做不同的事情。 在某些情况下,它是一个语句,而不是一个表达式,因此不能组合成更大的表达式。 在某些情况下,它返回分配的值,但仅作为值(通常称为右值),而不是本身可以修改或分配的值(左值)。 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/ 或任何其他需要赋值左值的操作,它将首先执行赋值,然后进一步修改赋值给的左值。

Different languages do different things with the assignment operator. In some, it is a statement, not an expression, so can't be combined into a larger expression. In some, it returns the value assigned, but only as a value (often called an rvalue), not as something that itself can be modified or assigned (an lvalue). An example of this is C, where you
can write:

 a = b = c;  # assign value of c to b and a

but not:

 ++(b = a);  # assign value of a to b, then increment b

And in some, the result of an assignment is the lvalue assigned to. (In Perl, this applies only to scalar assignments; list assignments are a more complex beast.) So you can do ++($b=$a) or ($b=$a) =~ s/a/b/ or any other operation that expects an lvalue on the assignment, and it will first do the assignment and then further modify the lvalue assigned to.

我是男神闪亮亮 2024-07-17 02:19:03

如果在 Q2 中您打算从 $a 中获取子字符串,您可能会发现这个习惯用法很有用:

($b) = $a =~ /(substring-to-match)/;
$b =~ s/regex-on-susbtring/result-string/;

另外请注意,$a 和 $b 不是 Perl 中的普通变量,因为它们具有与排序函数相关的特殊作用域规则。 有关详细信息,请参阅“perldoc perlvar”。

If in Q2 you mean to take a sub-string from $a, you might find this idiom useful:

($b) = $a =~ /(substring-to-match)/;
$b =~ s/regex-on-susbtring/result-string/;

Also do note that $a and $b are not normal variables in Perl since they have special scope rules related to the sort function. See 'perldoc perlvar' for details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文