2012-02-09 51 views
7

我有一個像java的正則表達式量詞

String string = "number0 foobar number1 foofoo number2 bar bar bar bar number3 foobar"; 

我需要一個正則表達式來給我下面的輸出字符串:

number0 foobar 
number1 foofoo 
number2 bar bar bar bar 
number3 foobar 

我已經試過

Pattern pattern = Pattern.compile("number\\d+(.*)(number\\d+)?"); 
Matcher matcher = pattern.matcher(string); 
while (matcher.find()) { 
    System.out.println(matcher.group()); 
} 

但是這給

number0 foobar number1 foofoo number2 bar bar bar bar number3 foobar 
+0

你的字符串中是否有換行符? – 2012-02-09 07:17:53

+0

是的,我不得不添加Pattern.DOTALL,它的工作原理。非常感謝。 – b3bop 2012-02-09 07:23:36

回答

10

所以你想要number(+一個整數)後跟任何東西,直到下一個number(或字符串的結尾),對不對?

然後,你需要告訴的正則表達式引擎:

Pattern pattern = Pattern.compile("number\\d+(?:(?!number).)*"); 

在你的正則表達式,匹配的多,因爲它可以在.* - 一切,直到字符串的結尾。此外,你做了第二部分(number\\d+)?比賽本身的一部分。

我的解決方案的說明:

number # Match "number" 
\d+  # Match one of more digits 
(?:  # Match... 
(?!  # (as long as we're not right at the start of the text 
    number # "number" 
)  # ) 
.  # any character 
)*  # Repeat as needed. 
+1

這是完美的。特別感謝解釋。 – b3bop 2012-02-09 07:17:40

+1

@Tim Pietzcker,謝謝你的回答!我總是喜歡閱讀你的詳細解釋。 – aviad 2012-02-09 07:30:17

0

因爲.*是一個貪婪的模式。使用.*?代替.*

Pattern pattern = Pattern.compile("number\\d+(.*?)(number\\d+)"); 
Matcher matcher = pattern.matcher(string); 
while(matcher.find();){ 
    out(matcher.group()); 
} 
+0

這不會起作用 - 它只匹配'number0','number1','number2'和'number3'。 – 2012-02-09 07:15:51

+0

我編輯了答案 – shift66 2012-02-09 07:19:42

+0

它仍然與正確的內容不匹配,測試字符串的結果是'number0 foobar number1'和'number2 bar bar bar bar number3'。你沒有測試你的代碼嗎?(如果字符串中有奇數個數字,它也會失敗) – 2012-02-09 07:48:01

0

如果「foobar的」僅僅是一個例子,你真正的意思是「任何詞」使用下面的模式:你的正則表達式的(number\\d+)\s+(\\w+)

+0

在number2 bar bar bar bar上失敗 – 2012-02-09 07:14:47

+0

對。沒有注意多個'bar',但這不是問題需要解決:(number \\ d +)(?:\ s +(\\ w +))+ – AlexR 2012-02-09 07:35:15

0

你爲什麼不只是匹配number\\d+,查詢匹配的位置,並執行字符串分割自己呢?

0
Pattern pattern = Pattern.compile("\\w+\\d(\\s\\w+)\1*"); 
Matcher matcher = pattern.matcher(string); 

while (matcher.find()) { 
    System.out.println(matcher.group()); 
} 
+0

很好的使用[backreference](https://docs.oracle.com/javase/tutorial/essential /regex/groups.html)!然而,這在嘗試匹配「number4 bar foo bar」時不起作用,這可能是OP所瞄準的目標(在這種情況下,返回的是「number4 bar」而不是「number4 bar foo bar」)。 – 2015-12-23 22:57:13