我在这里安装了这个程序来搜索句子中的连词。 我做了一个数组:
public static final String[] SUB_CONJS = new String[] {
"after", "afterwards", "although", "as if",
"as long as", "as much as", "as soon as",
"as though", "because", "before", "by the time",
"even if", "even though", "if", "in order that"...
//some more
};
如您所见,有一些重复,例如“if”
和“as if”
我使用匹配器来搜索它们:
String toSearch = "(?i)\\b(" + String.join("|", SUB_CONJS) + ")\\b";
Pattern pattern = Pattern.compile(toSearch);
Matcher matcher = pattern.matcher(text);
int count = 0;
while (matcher.find()) count++;
例如,如果我将 "as if"
放入 text
中,count
等于 2,因为匹配器搜索了 "if “
和 “好像”
。有解决问题的方法吗?谢谢
最佳答案
正如 Pshemo 所写,您的代码示例在测试字符串 "as if"
时返回所需的结果:1 个匹配。
这是因为“if”
不是“as if”
的前缀。事实上,除了 Pshermo 所说的之外,"if"
和 "as if"
在正则表达式中出现的顺序并不重要,因为它们不是彼此的前缀.
当您将“as”
添加到列表中以“as”开头的其他术语之前时,事情会变得更加复杂。在这种情况下,正则表达式实际上“消耗”了“as”,而忽略了潜在的更长匹配。
通过在搜索之前对搜索词进行相应排序,可以轻松解决此问题:
Comparator<String> prefixesLast = (s1, s2) -> {
if (s1.startsWith(s2)) return -1;
if (s2.startsWith(s1)) return 1;
return s1.compareTo(s2);
};
或者,为了更简单,只需按字符串顺序排序,但降序:
Comparator<String> descending = (s1, s2) -> return s2.compareTo(s1);
使用排序列表生成正则表达式应确保始终找到最长的匹配项。
关于java - 正则表达式匹配器防止重复搜索字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43829390/