2016-09-14 115 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

相關問題