2009-10-28 107 views
2

如何使用smartmatch操作符(~~)將其寫入?我可以使用Perl中的smartmatch運算符替換綁定運算符嗎?

use 5.010; 

my $string = '12 23 34 45 5464 46'; 

while ($string =~ /(\d\d)\s/g) { 
    say $1; 
} 
+0

這功課嗎? – 2009-10-28 15:08:05

+0

爲什麼這是作業?如果這是作業呢? – innaM 2009-10-28 15:13:28

+1

你需要什麼具體的匹配運算符來做?目前還不清楚你想要什麼。 – chollida 2009-10-28 15:14:20

回答

1

如果我們去看看這兩個變體是如何轉換的,我們可以看到原因。


  • 首先讓我們看一下原始版本。

    perl -MO=Deparse -e'while("abc" =~ /(.)/g){print "hi\n"}' 
    
    while ('abc' =~ /(.)/g) { 
        print "hi\n"; 
    } 
    

    正如你可以看到有沒有操作碼的任何變化。

  • 現在,如果你去改變它使用智能匹配運算符,你可以看到它確實發生了變化。

    perl -MO=Deparse -e'while("abc" ~~ /(.)/g){print "hi\n"}' 
    
    while ('abc' ~~ qr/(.)/g) { 
        print "hi\n"; 
    } 
    

    它它變爲qr,它不承認/g選項。

    這應該可能會給你一個錯誤,但它不會被轉換,直到它被解析。


    你應該得到的,如果你使用qr,而不是會得到警告:

    syntax error at -e line 1, near "qr/(.)/g"


智能匹配功能,從來沒有打算更換=~運營商。它出現在使given/when像它一樣工作的過程中。

在大多數情況下,when(EXPR)被視爲的$_隱式smart match
...

+0

這是我的想法 - 用「~~」替換「=〜」。 Perl6是否只有智能匹配運算符或會有「=〜」? – 2009-10-29 18:05:08

4

有趣。 perlsyn狀態:

任何~~正則表達式匹配$a =~ /$b/

所以,乍一看,似乎是合理的預期

use strict; use warnings; 
use 5.010; 

my $string = '12 23 34 45 5464 46'; 

while ($string ~~ /(\d\d)\s/g) { 
    say $1; 
} 

打印1223等,但它卡住在循環中,重複匹配12。使用:

 
$ perl -MO=Deparse y.pl 

產生

while ($string ~~ qr/(\d\d)\s/g) { 
    say $1; 
} 

看着perlop,我們注意到

qr/STRING/msixpo 

注意, 'G' 未被列爲修飾符(邏輯上,對我來說)。

有趣的是,如果你寫:

my $re = qr/(\d\d)\s/g; 

perl barfs:

 
Bareword found where operator expected at C:\Temp\y.pl line 5, 
near "qr/(\d\d)\s/g" 
syntax error at C:\Temp\y.pl line 5, near "qr/(\d\d)\s/g" 

想必也應該說些什麼,如果一個無效的表達式是在代碼中使用上述

+0

@Sinan所以我不能用智能匹配運算符寫這個嗎? – 2009-10-28 16:21:17

+1

@sid_com我不認爲你可以,但我不知道這種行爲是否由設計。 – 2009-10-28 16:25:54

+0

我猜你在跑過Deparse的地方存在一個錯誤。當我使用他輸入的代碼時,我得到:'while($ string =〜/(\ d \ d)\ s/g)'。作爲一個匹配的正則表達式(來自perlsyn),它應該有'g'運算符。我會檢查你的perl安裝。 = - [ – 2009-10-29 20:42:14

0

是的預期的行爲輸出到無盡的第一場比賽?因爲這是這個代碼必須以當前形式做的事情。問題不在於智能匹配運算符。 while循環是無止境的,因爲$string沒有發生任何修改。全局開關/g不會更改環路本身。

你想達到什麼目的?我假設你想輸出兩位數值,每行一個。在這種情況下,您可能需要考慮:

say join("\n", grep { /^\d{2}$/ } split(" ",$string)); 
+0

我試圖用「~~」來改變「=〜」。但由於它不起作用,我會使用「=〜」。 – 2009-10-29 18:06:30

-1

說實話,我不知道,你可以使用智能匹配運營商這一點。在我有限的測試中,它看起來像智能匹配是返回一個布爾值而不是匹配列表。但是,您發佈的代碼(使用=~)無法使用它。
由於while循環,您發佈的內容不起作用。在每次迭代開始之前執行while循環上的條件語句。在這種情況下,您的正則表達式會返回$string中的第一個值,因爲它在每次迭代時都會重置。 A foreach可以工作:

my $string = '12 23 34 45 5464 46'; 
foreach my $number ($string =~ /(\d\d)\s/g) { 
    print $number."\n"; 
} 
+0

完全錯誤並且不合格。首先,在'while'循環中使用'$ string =〜s /// g'不僅非常好,而且在很多情況下比'for'循環更可取。其次,你錯過了OP正在談論智能匹配運算符'~~'而不是'=〜'的事實。 – 2009-10-29 20:58:30

+0

雖然他沒有使用/// g'。他基本上使用'm /// g'。你對智能操作員是正確的,我會編輯修復這一點。 – 2009-10-29 21:04:48

+0

我的意思是'm //',而我對'///'所說的內容適用於'while'和'for'循環中的'm //'。 – 2009-10-29 21:34:27

相關問題