【问题标题】:What does the Perl substitution operator act on?Perl 替换运算符的作用是什么?
【发布时间】:2008-12-07 01:38:14
【问题描述】:

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

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

Q1) 这里发生了什么?正则表达式到底是在什么情况下运行的?

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

Q3) 如何使用循环默认变量作为初始字符串来执行此操作?

提前向 Perl 的梦想家们道歉,因为上面的内容看起来非常自然。

【问题讨论】:

    标签: regex perl substitution


    【解决方案1】:

    嗯...($lotr=$hobbit) =~ s/Bilbo/Frodo/g 是 Perl 的众多魔法之一。现在寻求一些答案。

    Q1) $lotr 被分配了包含在 $hobbit 中的值。赋值后,我们可以忘记源变量。将($lotr = $hobbit) 视为它自己的声明,就好像我们已经写过一样:

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

    相反。正则表达式在 $lotr 上运行。

    Q2) 语法只是上面给出的 sn-p 的单行版本。将其视为“从$a 复制字符串,将其复制到$b,并使用正则表达式修改$b”而不是“从$a 获取字符串,使用正则表达式对其进行修改,将结果放在@ 987654331@"

    Q3)我假设您的意思是“循环默认变量”的默认模式搜索空间?在这种情况下,只需使用$_ 而不是$hobbit

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

    有趣的是,这个操作并没有修改魔法变量$_。这样您就可以得出这样的结论:赋值发生在 正则表达式替换之前,并且替换不会以任何方式在默认模式空间上进行交互。

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

    【讨论】:

    • 那个答案是正确的。我正在输入它,因为这是发布的。顺便说一句,它(解决方案)花了我一个谷歌搜索找到。
    • @D.Shawley。吉斯伙计。从你上面所说的,为什么要修改 $_ ? “将字符串从 $a ($_) ... 复制到 $b ($lotr) 并使用正则表达式修改 $b ($lotr),将结果放在 $b ($lotr) 中”。 $_ 完全没有魔法。
    • 谢谢你,肖利先生。我一直在使用 IDL,而 IDL 没有就地操作符——一切都是 $y=f($x)。这种语法已经成为一种心理习惯,这使我无法深入了解基本的 Perl。感谢解锁。
    • @Rob -- 呵呵呵呵...出于某种原因,我总是希望 Perl 在你不注意的时候滑入$_ ;)
    【解决方案2】:

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

    【讨论】:

    • 谢谢,很高兴知道该示例的语法虽然不神奇,但却是 Perl 特有的。
    【解决方案3】:

    如果在 Q2 中您的意思是从 $a 中获取子字符串,您可能会发现这个习语很有用:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2010-11-28
      • 2011-11-02
      • 1970-01-01
      • 2010-09-28
      相关资源
      最近更新 更多