2016-09-14 110 views
7

我最近看到一些不熟悉Perl的人的代码。 他想比较两个字符串是否相等,但不知道 的eq运营商,所以他用=~这样的:

另一个片段被

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存在。这是为什么?我希望这是一个语法错误。

+3

您正在查看错误的文档部分:http://perldoc.perl.org/perlop.html#Binding-Operators – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot啊,谢谢你的联系。事实上,这是我正在寻找的信息。不过,应该有一些从“我的”部分到“你的”部分的链接。 – PerlDuck

+0

我认为很少有地方的文档中提到的例子是**/regex/**,但它的工作原理与**“正则表达式”**一样。例如,拆分工作就是这样。 – blackpen

回答

4

我以为是一个语法错误。

引用在perlop=~文档,

如果右边的参数是一个表达式,而不是一个搜索模式,置换或音译,它被解释为在运行时搜索模式。


但显然的Perl理解$str1 =~ "foo"作为$str1 =~ m/foo/虽然没有m存在。这是为什么?

为什么不呢?如果在RHS上没有匹配,替换或音译运算符,我想不出有没有=~意味着匹配运算符的原因。我会用

$s =~ /foo/ 

$s =~ "foo" 

,但我已经使用

$s =~ $re 

尤其当$re值是qr//编译的模式。

+0

我完全同意。我通常使用'/ foo /'或'$ s =〜$ re'(给出'$ re = qr/... /'),但想知道为什么'$ s =〜“foo”'起作用,因为我找不到文档为此。 – PerlDuck

+1

很明显,因为它已经编程,要做到这一点。实际上,它被记录为“如果正确的参数是表达式而不是搜索模式,替换或音译,则在运行时将其解释为搜索模式。” – ikegami

+0

我正在查看文档的错误部分。我读了['m //'和Regexp-Quote-Like-Operators](http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators),但应该阅读['=〜 '](http://perldoc.perl.org/perlop.html#Binding-Operators)。后者清除了一切。谢谢。 – PerlDuck

3

=~运算符期望标量表达式不在左边,模式匹配在右边。 From the documentation

二进制“=〜”将标量表达式绑定到模式匹配。某些操作默认搜索或修改字符串$ _。这个操作符使这种操作在其他一些字符串上工作。正确的参数是搜索模式,替换或音译。左边的参数是应该搜索,替换或音译的内容,而不是默认的$ _。
...
如果正确的参数是一个表达式而不是搜索模式,替换或音译,则在运行时将其解释为搜索模式

对右侧的实际解释可能会...非常棘手。详细信息可以在Perl文档的"Gory Details of Parsing Quoted Constructs"可以发现,总结其中的是:

当的东西,可能有几种不同的解释提出,Perl使用DWIM(这就是“做我的意思”)的原则挑选最可能的解释。这个策略非常成功,Perl程序员经常不会怀疑他们写的东西是否有矛盾。但是有时候,Perl的概念与作者的真正含义差别很大。
...
最重要的Perl解析规则是下面讨论的第一个:在处理带引号的构造时,Perl首先找到该构造的结尾,然后解释其内容。如果你理解这个规则,你可以在第一次阅读时跳过本节的其余部分。其他规则可能会比第一条规定更不经常地与用户的期望相抵触。

+0

没有什么棘手的。正如我在下面提到的,如果RHS不是明确的匹配,替换或音译运算符,则它是隐式匹配运算符。 – ikegami

+0

重新“*当提出可能有几种不同解释*的东西时”,这里不是这种情况。没有语法歧义。只有一种可能的解释。这一段与手头的问题无关。 – ikegami

+0

“*最重要的Perl解析规则是下面讨论的第一个*”,我想你误解了这一段的意思,因为它与手头的问题没有关系。它解释了为什么''foo $ foo {“bar”} bar“'是一个语法错误。 – ikegami

相关问题