2017-04-17 70 views
1

我目前正在嘗試檢測用戶給出的文本內的任何列表。我似乎無法正確檢測具有正則表達式的列表。如何使用正則表達式檢測文本中的多個列表?

示例文本

a, b, c and d, or e 

規則集

\w+(,?\s*\w+)+,?\s*(and|or) 

與左側一個字開始足以滿足我的使用情況(第一\w+表示)。使用Regular Expressions 101來測試正則表達式,顯示它在上面的示例文本中工作得很好。

使用Java的Matcher類,我可以簡單地檢查了最後一組無論是,檢測連詞的「類型」(這麼說)。

然而,更復雜的輸入將導致上市的錯誤檢測。也就是說,多個列表被檢測爲一個而不是多個

多個列表實施例

a, b, c and d, or e but not f, g, h and i, or j 

再次,Regular Expressions 101只有一個列表測試被檢測到(從文本的開頭到達直到最後)。

那麼,如何將改變正則表達式來檢測多個列表,而不是所有目錄作爲一個?

而且,我很好與任何其他的解決方案了。我只是想盡可能地解決這個問題。


最後,有一些代碼可以看到一個示例實現。

import java.util.Arrays; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Main { 
    public static void main(String[] args) { 
     Matcher matcher = Pattern.compile("\\w+(,?\\s*\\w+)+,?\\s*(and|or)").matcher("a, b, c and d, or e but not f, g, h and i, or j"); 

     while(matcher.find()){ 
      String conjunctionType = matcher.group(matcher.groupCount()).toLowerCase(); 

      Arrays.asList(Conjunction.values()).forEach(type -> { 
       if(conjunctionType.equals(type.toString())){ 
        System.out.println("Type: " + type); 
        System.out.println("Match: " + matcher.group()); 
        // TODO: use the type for further processing 
       } 
      }); 
     } 
    } 
} 

連詞枚舉

public enum Conjunction { 
    AND, 
    OR; 

    @Override 
    public String toString(){ 
     return this.name().toLowerCase(); 
    } 
} 

輸出

Type: or 
Match: a, b, c and d, or e but not f, g, h and i, or 

所需的輸出

Type: or 
Match: a, b, c and d, or 
Type: or 
Match: f, g, h and i, or 

更新

我忘了提及,在上面的正則表達式的任何單個字母是詞語的任意量僅僅是佔位符。

一種更爲複雜的實施例

a, b with some other words, c and d , or e but not f, g, h or i, and j 

回答

0

我終於通過使正則表達式部分非找到了解決辦法貪婪。

(\b\w+\b\s*,??\s*)+, (or|and) 

注意??在正則表達式(見here瞭解更多信息)。最終結果見this example。雖然忽略了列表中的最後一個「項目」,但這足以滿足我的用例。

示例代碼

import java.util.Arrays; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Main { 
    public static void main(String[] args) { 
     String text = "a, b, c and d, or e but not f, g, h and i, or j"; 
     String pattern = "(\\b\\w+\\b\\s*,??\\s*)+, (or|and)";  

     Matcher matcher = Pattern.compile(pattern).matcher(text); 

     while(matcher.find()){ 
      String conjunctionType = matcher.group(matcher.groupCount()).toLowerCase(); 

      Arrays.asList(Conjunction.values()).forEach(type -> { 
       if(conjunctionType.equals(type.toString())){ 
        System.out.println("Type: " + type); 
        System.out.println("Match: " + matcher.group()); 
        // TODO: use the type for further processing 
       } 
      }); 
     } 
    } 
} 

輸出

Type: or 
Match: a, b, c and d, or 
Type: or 
Match: e but not f, g, h and i, or 
1

\w+未能從butnot區分a。看來,你必須做出一個逗號分隔符強制除非and使用,並明確定義and分隔符:

\w+(?:,\s*\w+(?:\s+and\s+\w+)?)+,?\s*(and|or) 

演示:https://regex101.com/r/NqlBLk/1

+0

+1使用'?',我沒有想到這一點。看來,我忘了提到一些方面,對不起 - 我會更新這個問題。 – mcuenez