2012-02-09 99 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