java正则表达式量词

java正则表达式量词,java,regex,Java,Regex,我有一根像 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+)

我有一根像

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

所以你想要
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.

因为
*
是一种贪婪的模式。使用
*?
而不是
*

Pattern pattern = Pattern.compile("number\\d+(.*?)(number\\d+)");
Matcher matcher = pattern.matcher(string);
while(matcher.find();){
    out(matcher.group());
}
如果“foobar”只是一个示例,您的意思是“任意单词”,请使用以下模式:
(number\\d+)\s+(\\w+)
(.*)
正则表达式的一部分是贪婪的,因此它会吃掉从该点到字符串末尾的所有内容。更改为非贪婪变量:
(.*)


为什么不直接匹配
number\\d+
,查询匹配位置,然后自己拆分字符串

第2条上失败。对。我没有注意多个
。但这不是一个要解决的问题:(number\\d+(\\s+(\\w+))+)这不起作用-这只匹配
number0
number1
number2
number3
。这不起作用-这只匹配
number0
number1
number2
number3
。第二组是可选的(无论如何,它不应该是匹配的一部分。它仍然与正确的内容不匹配。测试字符串的结果是
number0 foobar number1
number2 bar number3
。您没有测试代码吗?(如果字符串中有奇数的
number
s,它也会失败。)您的字符串中是否有换行符?是的,我必须添加Pattern.DOTALL,它很有效。非常感谢您。@Tim Pietzcker,谢谢您的回答!我一直很喜欢阅读您的详细解释。很好地使用了!但是,当尝试匹配“number4 bar foo bar”时,这将不起作用,这可能是OP的目标(在这种情况下为“number4 bar”返回,而不是“数字4 bar foo bar”)。
Pattern pattern = Pattern.compile("\\w+\\d(\\s\\w+)\1*");
Matcher matcher = pattern.matcher(string);

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