使用双感叹号在perl中匹配cond
matching cond in perl using double exclaimation
if ($a =~ m!^$var/!)
$var
是二维散列中的键,$a
是另一个散列中的键。
这些表达式是什么意思?
这是一个regular expression ("regex"), where the !
character is used as the delimiter for the pattern that is to be matched in the string that it binds to via the =~
operator(这里是$a
†)。
可能会考虑使用通常的定界符 $a =~ /^$var\//
来考虑相同的正则表达式(然后可以省略 m
);但是现在显然必须转义模式中使用的任何 /
。为了避免难看和嘈杂的 \/
组合,人们经常使用另一个字符作为分隔符,因为几乎可以使用任何字符(我最喜欢的是卷曲,m{^$var/}
)。 ‡ §
问题中的这个正则表达式测试变量 $a
中的值是否以(通过 ^
anchor)变量的值 $var
开头,然后是 /
(评估变量并使用结果)。 §
† 不是变量名的好选择,因为 $a
和 $b
被内置 sort
[=43= 使用]
‡ 有了提前准备好的模式,甚至不需要分隔符
my $re = qr{^$var/};
if ($string =~ $re) ...
(但我还是喜欢用 //
然后,发现它更清晰)
上面我使用了 qr,但是一个简单的 q()
就可以了(虽然我绝对推荐 qr
)。这些也几乎可以使用任何字符作为分隔符。
§ 在一个模式中,评估的变量被用作正则表达式模式,一般来说这是错误的(当这是预期的时候,它们应该使用 qr
进行编译,因此用作子模式)。
一个缺乏想象力的例子:一个变量 $var = q(\s)
(文字反斜杠后跟字母 s
)在一个模式中计算产生 \s
序列,然后将其视为正则表达式模式,因为空格。 (大概是无意的;我们只是想要 \
和 s
。)
这可以通过使用 quotemeta、/\Q$var\E/
来补救,以便转义 $var
中可能的元字符;这导致文字字符的正确模式 \s
。所以正确的写法是 m{^\Q$var\E/}
.
不这样做也会导致注入错误。感谢 ikegami 对此发表评论。
匹配运算符 (m/.../
) 是 Perl 的“类引号”运算符之一。标准用法是在运算符中间的正则表达式前后使用斜杠(如果使用斜杠,则可以省略运算符开头的 m
)。但是,如果正则表达式本身包含一个斜线,那么使用不同的分隔符来避免必须转义嵌入的斜线会很方便。在您的示例中,作者决定使用感叹号,但可以使用任何非空白字符。
许多 Perl 运算符都是这样工作的 - m/.../
、s/.../.../
、tr/.../.../
、q/.../
、qq/.../
、qr/.../
、qw/.../
, qx/.../
(我可能忘记了一些)。
if ($a =~ m!^$var/!)
$var
是二维散列中的键,$a
是另一个散列中的键。
这些表达式是什么意思?
这是一个regular expression ("regex"), where the !
character is used as the delimiter for the pattern that is to be matched in the string that it binds to via the =~
operator(这里是$a
†)。
可能会考虑使用通常的定界符 $a =~ /^$var\//
来考虑相同的正则表达式(然后可以省略 m
);但是现在显然必须转义模式中使用的任何 /
。为了避免难看和嘈杂的 \/
组合,人们经常使用另一个字符作为分隔符,因为几乎可以使用任何字符(我最喜欢的是卷曲,m{^$var/}
)。 ‡ §
问题中的这个正则表达式测试变量 $a
中的值是否以(通过 ^
anchor)变量的值 $var
开头,然后是 /
(评估变量并使用结果)。 §
† 不是变量名的好选择,因为 $a
和 $b
被内置 sort
[=43= 使用]
‡ 有了提前准备好的模式,甚至不需要分隔符
my $re = qr{^$var/};
if ($string =~ $re) ...
(但我还是喜欢用 //
然后,发现它更清晰)
上面我使用了 qr,但是一个简单的 q()
就可以了(虽然我绝对推荐 qr
)。这些也几乎可以使用任何字符作为分隔符。
§ 在一个模式中,评估的变量被用作正则表达式模式,一般来说这是错误的(当这是预期的时候,它们应该使用 qr
进行编译,因此用作子模式)。
一个缺乏想象力的例子:一个变量 $var = q(\s)
(文字反斜杠后跟字母 s
)在一个模式中计算产生 \s
序列,然后将其视为正则表达式模式,因为空格。 (大概是无意的;我们只是想要 \
和 s
。)
这可以通过使用 quotemeta、/\Q$var\E/
来补救,以便转义 $var
中可能的元字符;这导致文字字符的正确模式 \s
。所以正确的写法是 m{^\Q$var\E/}
.
不这样做也会导致注入错误。感谢 ikegami 对此发表评论。
匹配运算符 (m/.../
) 是 Perl 的“类引号”运算符之一。标准用法是在运算符中间的正则表达式前后使用斜杠(如果使用斜杠,则可以省略运算符开头的 m
)。但是,如果正则表达式本身包含一个斜线,那么使用不同的分隔符来避免必须转义嵌入的斜线会很方便。在您的示例中,作者决定使用感叹号,但可以使用任何非空白字符。
许多 Perl 运算符都是这样工作的 - m/.../
、s/.../.../
、tr/.../.../
、q/.../
、qq/.../
、qr/.../
、qw/.../
, qx/.../
(我可能忘记了一些)。