在Java中使用正则表达式多次匹配一个字符串

我在制作以下正则表达式时遇到了一些问题。 我想要以下字符串:

"Please enter your name here" 

生成包含以下元素的数组:

 'please enter', 'enter your', 'your name', 'name here' 

目前,我使用以下模式,然后创建匹配器并以下列方式迭代:

 Pattern word = Pattern.compile("[\w]+ [\w]+"); Matcher m = word.matcher("Please enter your name here"); while (m.find()) { wordList.add(m.group()); } 

但我得到的结果是:

 'please enter', 'your name' 

我究竟做错了什么? (Ps,我在regexpal.com上检查了相同的正则表达式并遇到了同样的问题)。 似乎同一个单词不会匹配两次。 我能做些什么才能达到我想要的效果?

谢谢。

———————————

编辑:感谢您的所有建议! 我最终这样做了(因为它增加了灵活性,可以轻松指定“n-gram”的数量):

 Integer nGrams = 2; String patternTpl = "\\b[\\w']+\\b"; String concatString = "what is your age? please enter your name." for (int i = 0; i < nGrams; i++) { // Create pattern. String pattern = patternTpl; for (int j = 0; j < i; j++) { pattern = pattern + " " + patternTpl; } pattern = "(?=(" + pattern + "))"; Pattern word = Pattern.compile(pattern); Matcher m = word.matcher(concatString); // Iterate over all words and populate wordList while (m.find()) { wordList.add(m.group(1)); } } 

这导致:

 Pattern: (?=(\b[\w']+\b)) // In the first iteration (?=(\b[\w']+\b \b[\w']+\b)) // In the second iteration Array: [what, is, your, age, please, enter, your, name, what is, is your, your age, please enter, enter your, your name] 

注意:从以下顶部答案获得模式: Java正则表达式跳过匹配

匹配不能重叠,这可以解释您的结果。 这是一个潜在的解决方法,利用具有积极前瞻性的捕获组 :

 Pattern word = Pattern.compile("(\\w+)(?=(\\s\\w+))"); Matcher m = word.matcher("Please enter your name here"); while (m.find()) { System.out.println(m.group(1) + m.group(2)); } 
请输入
输入您的
你的名字
在这里命名

如果您想避免使用这种特定的RegEx,也许您应该尝试一种更简单,更简单的解决方案:

 public static String[] array(final String string){ final String[] words = string.split(" "); final String[] array = new String[words.length-1]; for(int i = 0; i < words.length-1; i++) array[i] = String.format("%s %s", words[i], words[i+1]); return array; } public static void main(String args[]){ final String[] array = array("Please enter your name here"); System.out.println(Arrays.toString(array)); } 

输出是:

[Please enter, enter your, your name, name here]

你没有做错任何事。 这只是正则表达式的工作方式(否则匹配将变为O(n ^ 2),因为正则表达式匹配是在线性时间内完成的,这是无法处理的)。

在这种情况下,您只需搜索[\w]+ 。 并对这些组进行后处理。

就像是:

 Pattern word = Pattern.compile("(\\w+) ?"); Matcher m = word.matcher("Please enter your name here"); String previous = null; while (m.find()) { if (previous != null) wordList.add(previous + m.group(1)); previous = m.group(); } 

模式以可选空格结束(如果字符串中有更多空格,则匹配)。 m.group()返回整个匹配,带空格; m.group(1)只返回单词,没有空格。