我在制作以下正则表达式时遇到了一些问题。我想要以下字符串:
"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'
我做错了什么? (P.,我在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 regex skipping matches
答案 0 :(得分:5)
匹配不能重叠,这可以解释您的结果。这是一个潜在的解决方法,将capturing groups与positive lookahead:
结合使用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));
}
Please enter enter your your name name here
答案 1 :(得分:1)
如果你想避免使用这种特定的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]
答案 2 :(得分:0)
你没有做错任何事。它只是正则表达式的工作方式(否则匹配将变为O(n ^ 2),因为正则表达式匹配是在线性时间内完成的,无法处理)。
在这种情况下,您只需搜索[\w]+
即可。并对这些组进行后处理。
答案 3 :(得分:0)
类似的东西:
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)
只返回单词,没有空格。