2013-01-24 66 views
8

爲了重新產生問題,因爲在最近的問題陳述(*)(+) - Why does (.*)* make two matches and select nothing in group $1?我試着括號內外的*+的各種組合,並且我得到的結果不是預期的。奇怪的問題與`(*)*`,`+`,`*`在Java中的正則表達式

我本來會期望輸出的結果與在該問題中接受的答案中所解釋的相同,也是在另一個重複問題中,標記爲Perl-Why doesn't the .* consume the entire string in this Perl regex?。但它的行爲不一樣。

爲簡單起見,這裏是我試過的代碼: -

String str = "input"; 
String[] patterns = { "(.*)*", "(.*)+", "(.+)*", "(.+)+" }; 

for (String pattern: patterns) { 
    Matcher matcher = Pattern.compile(pattern).matcher(str); 

    while (matcher.find()) { 
     System.out.print("'" + matcher.group(1) + "' : '" + matcher.start() + "'" + "\t"); 
    } 

    System.out.println(); 
} 

這是我得到了所有4個組合輸出: -

'' : '0' '' : '5'   // For `(.*)*` 
'' : '0' '' : '5'   // For `(.*)+` 
'input' : '0' 'null' : '5' // For `(.+)*` 
'input' : '0'     // For `(.+)+` 

現在,我可以」不懂,爲什麼在1st2nd輸出,我沒有得到整個字符串作爲first resultmatcher.find()。我的意思是,理想情況下,在第一種情況下,.*應首先捕獲整個字符串,然後在最後捕獲empty string。現在,雖然它在第二場比賽中取得了預期的成績,但對於1st match表現不佳。

而且也,在第2個的情況下,我不應該連得第二節比賽,因爲我在支架外的+量詞。

我的預期成果是: -

'input' : '0' '' : '5' // For 1st 
'input' : '0' // For 2nd 

此外,在3rd輸出,爲什麼我null爲第二節比賽,而不是empty string?第三組合的第二場比賽應該不會相同嗎?

第四輸出是按期望。所以,毫無疑問。

+0

只是一個側面說明:是否有理由爲什麼你不使用for循環來循環正則表達式?您的代碼提醒我關於http://www.codecrap.com –

+0

@SimonAndréForsberg的代碼。正如我所說,我只是在重現前一個問題的問題。這不是我將要使用的代碼。所以,我只是匆忙編碼。我會修改它看起來很漂亮。 –

+0

提示:嘗試'matcher.group(0)'查看整個比賽,而不僅僅是第一個捕獲組。 –

回答

7

你看到你的問題看你鏈接到同一個現象的影響:

對於(.*)*

  • 第一matcher.start()0是因爲那裏的比賽("input")開始。
  • 第一matcher.group(1)"",因爲重複(.*)已重寫的捕獲"input"與空字符串(但matcher.group(0)確實含有input")。
  • 第二matcher.start()5因爲那裏正則表達式引擎是第一個成功匹配後。
  • 第二個matcher.group(1)(以及matcher.group(0))是"",因爲這就是匹配字符串末尾的所有內容。

對於(.*)+這是一樣的。畢竟,空字符串可以重複多次,並且仍然是空字符串。

(.+)*null因爲在第二場比賽成功(長度1匹配空字符串的字符串的零個重複),在捕獲括號一直沒能捕捉到任何東西,所以它的內容是null(如未定義,而不是空字符串)。

+0

+1喜歡這個解釋,特別是第三個。 :) –