2016-12-02 54 views
0

我想用Perl中的正則表達式理解情況。爲什麼一個單詞在正則表達式(perl)中打破所有正確的輸出?

$str = "123-abc 23-rr"; 

需要在減號旁邊顯示兩個單詞。 正則表達式是:

@mas=$str=~/(?:([\d\w]+)\-([\d\w]+))/gx; 

它顯示正確的輸出:123abc23rr。 但是,如果我改變串一點,把一個單詞的開始:

$str = "word 123-abc 23-rr"; 

而且我要考慮到這第一個字,所以我改變我的正則表達式:

@mas=$str=~/\w+\s(?:\s*([\d\w]+)\-([\d\w]+))*/gx; 

我的輸出必須相同,但有:23rr。如果我刪除\s**,則輸出爲123,abc。但它仍然是不正確的。有人知道爲什麼

+1

你可以閱讀關於*捕捉重複組* [這裏](http://www.regular-expressions.info/captureall.html) –

+0

當您指定輸入字符串的特定開始,你不能告訴引擎在大量的正則表達式上進行'全局'匹配。 – revo

+0

另請參閱[重複捕獲和解析](http://blogs.perl.org/users/sirhc/2012/05/repeated-capturing-and-parsing.html)。請注意,它不是第一個「\ w +」是「罪魁禍首」,而是您在非捕獲組上設置的'*'量詞。 –

回答

1

與其給一個更具體的字符串做一個更具體的正則表達式,考慮利用整體模式。

  1. 每件被空格分開。
  2. 第一件是一個詞。
  3. 其餘的是由破折號分隔的對。

首先拆分空白部分。

my @pieces = split /\s+/, $str; 

然後刪除第一塊,它不必拆分。

my $word = shift @pieces; 

然後將每條分割上-成對。

my %pairs = map { split /-/, $_ } @words; 
+0

好吧,您更喜歡其他方法,非常有趣。我會試試這個 – Log

1

對於每個匹配,每個捕獲都會返回。


在第一個片段中,模式匹配兩次。

123-abc 23-rr 
\_____/ \___/ 

有兩個捕獲,所以返回四個(2 * 2 = 4)值。


在第二個片段中,模式匹配一​​次。

word 123-abc 23-rr 
\________________/ 

有兩種捕捉,於是兩個返回(2×1 = 2)的值。

+0

但爲什麼是2值?如果我寫(...)*,星號採取最大巧合,因爲它是貪婪,如果我知道它 – Log

+0

我的意思是爲什麼我的建設不擴大在 /\ w +([\ d \ w] +)\ - ([\ d \ w] +)([\ d \ w] +)\ - ([\ d \ w] +)引擎 – Log

+0

如果這就是您想要的,請告訴它。否則,它會阻止人們執行'if(/(.)(?:(.)\2)*(.)/){print $ 3}' – ikegami

相關問題