在使用QQ的变量声明上使用匹配操作员时,为什么括号本身围绕声明本身起作用

  • 本文关键字:声明 起作用 变量 QQ 操作员 perl
  • 更新时间 :
  • 英文 :


我知道标题是一个嘴巴,但我不确定如何使其更简洁。

阅读perl I中的多行字符串,我在Perlmaven遇到了有关此处介绍的这篇文章。它讨论了这里的 qqq。在所有情况下,都保留了领先的空格(如代码凹痕)。我明白那个。在示例显示的方法中,这种方法的方法是使用正则替换来删除领先的空间。

if ($send) {
    (my $message = qq{
        Dear $name,
        this is a message I plan to send to you.
        regards
          the Perl Maven
        }) =~ s/^ {8}//mg;
    print $message;
}

当我试图采用这种风格时,我(偶然地)这样写了它:

if ($send) {
    my $message = (qq{
        Dear $name,
          words and stuff
        }) =~ s/^ {8}//mg;
    print $message;
}

perl对我来说不是强大的语言。我在上面尝试过的不正确的语法对我来说很自然。由于我错误地使用了匹配操作员,因此显然会出现错误:

无法在nagios_send_html_service_mail.pl line 91中修改替换(s///)中的字符串,靠近" s/^ {8}//mg;" >

在工作示例中为什么 $message实际包含更改?当您声明变量时,我似乎允许您做的事情,但我只是想知道它叫什么。

因为这是关于您要更改的内容。

=~是绑定操作员,并告诉您将模式匹配应用于什么。

my $message = "fish";
   $message =~ s/i/a/; 
print $message

会起作用,因为您正在尝试转换$message。这是第一个示例中发生的事情 - 消息是设置 first ,然后由于括号而应用了修改。

但是,=~的绑定比=更紧密。它首先发生。

perldoc perlop

记录了此优先级

因此,在第一个示例中 - 分配是由于支架而首先发生的,然后转换。没有括号,它首先尝试转换:

"fish" =~ s/i/a/;

这是无效的,因为那时它没有更改变量,而是一个静态文本。

my $result = "fish" =~ s/i/a/; #gives same error.
( my $result = "fish" ) =~ s/i/a/; #works.

您可以使用r REGEX修饰符来返回一个值:

my $result = "fish" =~ s/i/a/r;

r标志停止尝试修改该值,然后"返回"操作的结果,然后可以将其分配给$result

=~的优先级高于 =,所以

my $message = (qq{...}) =~ s/^ {8}//mg;

等于

my $message = ( (qq{...}) =~ s/^ {8}//mg );

这试图修改qq返回的常数,这是不允许的。


标量上下文中的标量分配运算符返回其左侧(作为LVALUE) [1] 。这意味着

( $message = qq{...} ) =~ s/^ {8}//mg;

等于

$message = qq{...};
$message =~ s/^ {8}//mg;

此外, my $message返回 $message(作为lvalue),所以

( my $message = qq{...} ) =~ s/^ {8}//mg;

等于

my $message;
$message = qq{...};
$message =~ s/^ {8}//mg;

这就是为什么原始解决方案有效的原因。


请注意,缩进的更改将破坏您的代码,因此您的技术是脆弱的。考虑使用以下内容:

if ($send) {
    (my $message = qq{
        !Dear $name,
        !
        !this is a message I plan to send to you.
        !
        !regards
        !  the Perl Maven
    }) =~ s/^[^Sn]+[!n]?//mg;
    print $message;
}

上面还删除了不需要的空白领先线。


最后,请注意5.14中引入的r修饰符。

if ($send) {
    my $message = qq{
        !Dear $name,
        !
        !this is a message I plan to send to you.
        !
        !regards
        !  the Perl Maven
    } =~ s/^[^Sn]+[!n]?//mgr;
    print $message;
}

  1. 请参阅迷你教程:标量与列表分配运算符有关分配运营商返回的更多信息。

最新更新