Java中的非贪婪正则表达式

17

我有以下代码:

public static void createTokens(){
    String test = "test is a word word word word big small";
    Matcher mtch = Pattern.compile("test is a (\\s*.+?\\s*) word (\\s*.+?\\s*)").matcher(test);
    while (mtch.find()){
        for (int i = 1; i <= mtch.groupCount(); i++){
            System.out.println(mtch.group(i));
        }
    }
}

并且有以下输出:

word
w

但是在我看来,应该是这样的:

word
word

请有人解释一下为什么这样?

2个回答

19

因为你的模式是非贪婪的,所以它们尽可能匹配最少的文本,同时仍然符合匹配条件。

在第二个组中删除问号,你将得到
word
word word big small

Matcher mtch = Pattern.compile("test is a (\\s*.+?\\s*) word (\\s*.+\\s*)").matcher(test);

现在第二组捕获的内容太多了,而不是太少了。非贪婪模式不是问题的原因,贪婪模式也不是解决方案。 - Alan Moore
1
你说得对,但在我看来,第二个捕获组的非贪婪性解释了为什么它只捕获了“w”。第一个捕获组必须捕获“word”,因为它后面跟着“word”字面量。我不知道他具体想要什么,而且他在我提交答案后编辑了问题,所以我无法提供正确的正则表达式。 - theglauber

3
通过使用\\s*,它将匹配任意数量的空格,包括0个空格。w匹配(\\s*.+?\\s*)。为了确保它匹配由空格分隔的单词,请尝试(\\s+.+?\\s+)

问题在于,正则表达式已经消耗了单词前后的空格字符,所以现在你正在尝试两次消耗它们。 - Alan Moore
你需要做的就是从正则表达式中删除空格,例如...\\s+)word(\\s+... - Daniel Gray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接