2015-12-03 47 views
2

我試圖在Java中制定一個正則表達式來捕獲空格分隔列表中的多個字符串。這裏是我試圖從捕捉串...使用正則表達式在分隔列表中匹配子字符

String output = "regulations { qux def } standards none rules { abc-123 456-defghi wxyz_678 } security { enabled }"; 

而且我想用一個正則表達式匹配括號之間的空間分隔列表中的每個字緊隨rules。換句話說,我希望正則表達式匹配abc-123456-defghiwxyz_678。這個列表中的這些子字符串可以包含除空格之外的任何字符,並且列表中可以有任意數量的子字符串;我剛剛使用了上面的3個例子來舉例說明。以下是行不通的,因爲我需要修改它能夠匹配多次...

String regex = "rules\\s\\{\\s([^\\s]*)\\s\\}"; 
final Pattern pattern = Pattern.compile(regex); 
Matcher matcher = pattern.matcher(output); 
while (matcher.find()) { 
    System.out.println(matcher.group(1)); 
} 

我怎麼能修改上面的正則表達式來考慮多個可能的匹配,並得到下面的輸出?

abc-123 
456-defghi 
wxyz_678 
+0

你需要一個正則表達式的方法嗎?我認爲兩步法更具可讀性。 –

+0

說實話,我真的很感謝看到我自己的學習的單一和雙正則表達式的解決方案... – user2150250

回答

3

以下是一個步驟:使用1個正則表達式「匹配所有」。

regex

(?:\brules\s+\{|(?!^)\G)\s+([\w-]+) 

正則表達式是匹配隨後用1個或多個空格碼元的整個單詞rules,如果它發現1或多個空格,隨後的1個或多個字母數字符號或連字符的序列,它在最後的成功比賽之後也匹配。單詞rules對我們來說是一種界限。

Java code

String output = "regulations { qux def } standards none rules { abc-123 456-defghi wxyz_678 } security { enabled }"; 
String regex = "(?:\\brules\\s+\\{|(?!^)\\G)\\s+([\\w-]+)"; 
final Pattern pattern = Pattern.compile(regex); 
Matcher matcher = pattern.matcher(output); 
while (matcher.find()) { 
    System.out.println(matcher.group(1)); 
} 

這裏是一個兩步驟的方法:1)得到rules {},2)與空白組之間的子字符串。

String output = "regulations { qux def } standards none rules { abc-123 456-defghi wxyz_678 } security { enabled }"; 
String subst = output.replaceFirst("(?s)^.*\\brules\\s*[{]\\s*([^{}]+)[}].*$", "$1"); 
String[] res = subst.split("\\s+"); 
System.out.println(Arrays.toString(res)); 

請參閱IDEONE demoregex demo

正則表達式要簡單得多,它只是匹配所有直至幷包括rules {,然後捕獲什麼{...}裏面,然後匹配}和字符串的其餘部分。通過反向引用$1我們將此組1的值恢復爲subst變量。然後只是分裂。

+0

如果你願意,我會爲第一個正則表達式添加更多的解釋,我現在有點緊張。最主要的是它匹配和捕獲*規則{'後面的'([\ w - ] +)'所需的*。 –

+0

嗯,1步解決方案似乎只捕獲第一個子字符串「abc-123」。 https://regex101.com/r/rH6dH3/1 – user2150250

+0

你忘了'g'修飾符。在Java中,'/ g'是'while(m.find()){...}'。 –