2012-11-07 71 views
1

我試圖開發一個正則表達式來查找字符串內的標記序列。例如,我可以將標記(NP .*)至少一次(可以是多次),然後是標點符號(在此例中爲./.)。如果在(NP)./.之間還有另一個標記(如下面例子中的VP),Matcher一定不能找到任何東西。問題是,即使在.*之後使用問號,它也會繼續查找),從而使表達式匹配字符串中的某些內容。這裏是我的方法:Java上的正則表達式:避免Matcher類不必要的「貪婪」策略

public void myMethod() { 
    String input = "(NP first tag) (VP second tag) ./."; 
    String regex = "(\\(NP .*?\\)()?)+" + "\\./\\."; 

    Pattern pattern = Pattern.compile("(" + regex + ")"); 
    Matcher matcher = pattern.matcher(input); 

    if (matcher.find()) { 
     System.out.println("<S "+matcher.group(0)+">"); 
    } else { 
     System.out.println("sem grupos."); 
    } 
} 

該方法仍然會匹配正則表達式,但它不應該。我需要它告訴我沒有發現任何組,因爲「VP」標籤不應該在那裏。我相信這個問題依賴於Java中的正則表達式所採用的貪婪策略。它試圖找到一些與正則表達式相關的字符組合。我不知道如何重寫這個表達式。

任何幫助?

編輯:

1)我注意到,我的問題是有點混亂,所以我改變了一下讓它能夠更清晰。

2)謝謝Aan Moore。我同意我使用的組數多於必要數量,但是這是因爲像+這樣的運營商。我試圖砍掉不必要的羣體。另外你的簡單想法是用[^)]*?代替.*?太棒了!我唯一調整的是我通過使用[^\\)]*?逃脫)符號。下面我顯示最後使用的REGEX。

String regex = "(\\(NP [^\\)]*?\\) ?)+\\./\\."; 

非常感謝! :)

+0

你只想兩個標籤有: - 'NP'和'VP'?你實際上並不符合你的'VP'標籤? –

回答

1

((\(NP .*?\)()?)+\./\.)是編譯模式。

簡化:

\(NP .*?\) ?+\./\.刪除未使用的捕獲組。

現在,讓我們看看你有例子字符串:

(NP first tag) (VP second tag) ./.,該.*?比賽first tag) (VP second tag
(NP first tag) (VP second tag) (MISC tag that must not be catch) ./.,.*?匹配first tag) (VP second tag) (MISC tag that must not be catch

爲什麼?我的意思是,它不是很貪婪?對,但...

.*?\)開始匹配first tag),你想要什麼。然而,正則表達式的其餘部分未能通過匹配,正則表達式引擎會將其作爲可能的答案拋出並繼續查找。

如果你沒有像(NP(標籤)),可以換着花樣標籤標籤:\(NP [^)]*?\)

要匹配你在你的問題中描述的字符串:\(NP [^)]*?\) ?\(VP [^)]*?\) \./\.

與Java逃逸它變成\\(NP [^)]*?\\) ?\\(VP [^)]*?\\) \./\.

對於進一步的閱讀,有一個很大的Stack Overflow question覆蓋更多的理論和實踐解決這個的。

+0

您最近圖案可以進一步簡化爲: - ?'(\\?([NV] P [^)] * \\)){2}' –

+0

以這種方式簡化允許(VP)(NP),這是不像問題中所述。此外,至少有一個(NP)的標籤,而不僅僅是一個。 –

+0

@anonfunc ..是啊。抱歉。沒有注意到這一點。 –