我最近看到了一些不熟悉Perl的人的代码。
他想比较两个字符串的平等但不知道
eq
运算符,所以他使用=~
这样:
my $str1 = 'foobar';
my $str2 = 'bar';
if ( $str1 =~ $str2 ) {
print "strings are equal\n";
}
另一个片段是
if ( $str1 =~ "foo" ) {
print "string equals 'foo'\n";
}
当然,只需阅读$str1 eq $str2
和$str1 eq "foo"
即可避免误报。
我通过Deparse
运行代码,它说一切正常:
$ perl -MO=Deparse -e 'use strict;
use warnings;
my $str1="foobar";
my $str2="bar";
$str1 =~ $str2;
$str1 =~ "bar";'
use warnings;
use strict;
my $str1 = 'foobar';
my $str2 = 'bar';
$str1 =~ /$str2/;
$str1 =~ /bar/;
-e syntax OK
我查看了docs,但是根据我的理解 情况如下:
m/pattern/
。m
和您选择的分隔符而不是/
(但要注意'
和?
具有特殊含义) m
,但分隔符必须为/
。但显然Perl将$str1 =~ "foo"
理解为$str1 =~ m/foo/
,但不存在m
。这是为什么?我预计会出现语法错误。
答案 0 :(得分:5)
我希望这是一个语法错误。
在perlop,
中引用=~
的文档
如果右参数是表达式而不是搜索模式,替换或音译,则在运行时将其解释为搜索模式。
但显然Perl将
$str1 =~ "foo"
理解为$str1 =~ m/foo/
,但不存在m
。那是为什么?
为什么不呢?如果在其RHS上没有匹配,替换或音译操作符,我想不出有=~
暗示匹配运算符的原因。我用
$s =~ /foo/
在
$s =~ "foo"
但我用过
$s =~ $re
特别是当$re
的值是由qr//
编译的模式时。
答案 1 :(得分:3)
=~
运算符需要左边的标量表达式和右边的模式匹配。来自the documentation:
Binary" =〜"将标量表达式绑定到模式匹配。某些操作默认搜索或修改字符串$ _。此运算符使该类操作在其他字符串上运行。正确的参数是搜索模式,替换或音译。左参数是应该搜索,替换或音译的内容,而不是默认的$ _ ...
如果正确的参数是表达式而不是搜索模式,替换或音译,则在运行时将解释为搜索模式。
右手边的实际解释可能是......棘手的。详细信息可以在Perl文档的"Gory Details of Parsing Quoted Constructs"中找到,其摘要是:
当出现可能有多种不同解释的内容时,Perl使用 DWIM (即“我的意思和#34;”原则来选择最可能的解释。这种策略非常成功,以至于Perl程序员通常不会怀疑他们所写内容的矛盾心理。但Perl的观念不时与作者的真实含义大不相同 ...
最重要的Perl解析规则是下面讨论的第一个规则:在处理带引号的构造时,Perl首先找到该构造的结尾,然后解释其内容。如果您了解此规则,则可以在第一次阅读时跳过本节的其余部分。其他规则可能比第一个规则更不频繁地与用户的期望相矛盾。