使用Java正则表达式,如何检查字符串是否包含集合中的任何单词?
2022-09-01 05:12:48
我有一套词说 - 苹果,橙子,梨,香蕉,猕猴桃
我想检查一个句子是否包含上面列出的任何单词,如果包含,我想找到匹配的单词。如何在正则表达式中完成此操作?
我目前正在为我的每组单词调用String.indexOf()。我假设这不如正则表达式匹配有效?
我有一套词说 - 苹果,橙子,梨,香蕉,猕猴桃
我想检查一个句子是否包含上面列出的任何单词,如果包含,我想找到匹配的单词。如何在正则表达式中完成此操作?
我目前正在为我的每组单词调用String.indexOf()。我假设这不如正则表达式匹配有效?
TL;DR对于简单的子字符串是最好的,但对于仅匹配整个单词,正则表达式可能更好。
contains()
查看哪种方法更有效的最佳方法是对其进行测试。
您可以使用 代替 来简化非正则表达式代码。String.contains()
String.indexOf()
要搜索不同的单词,正则表达式如下所示:
apple|orange|pear|banana|kiwi
在正则表达式中用作 。|
OR
我非常简单的测试代码如下所示:
public class TestContains {
private static String containsWord(Set<String> words,String sentence) {
for (String word : words) {
if (sentence.contains(word)) {
return word;
}
}
return null;
}
private static String matchesPattern(Pattern p,String sentence) {
Matcher m = p.matcher(sentence);
if (m.find()) {
return m.group();
}
return null;
}
public static void main(String[] args) {
Set<String> words = new HashSet<String>();
words.add("apple");
words.add("orange");
words.add("pear");
words.add("banana");
words.add("kiwi");
Pattern p = Pattern.compile("apple|orange|pear|banana|kiwi");
String noMatch = "The quick brown fox jumps over the lazy dog.";
String startMatch = "An apple is nice";
String endMatch = "This is a longer sentence with the match for our fruit at the end: kiwi";
long start = System.currentTimeMillis();
int iterations = 10000000;
for (int i = 0; i < iterations; i++) {
containsWord(words, noMatch);
containsWord(words, startMatch);
containsWord(words, endMatch);
}
System.out.println("Contains took " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
matchesPattern(p,noMatch);
matchesPattern(p,startMatch);
matchesPattern(p,endMatch);
}
System.out.println("Regular Expression took " + (System.currentTimeMillis() - start) + "ms");
}
}
我得到的结果如下:
Contains took 5962ms
Regular Expression took 63475ms
显然,时间会根据要搜索的单词数和要搜索的字符串而有所不同,但对于像这样的简单搜索,似乎比正则表达式快约10倍。contains()
通过使用正则表达式在另一个字符串中搜索字符串,您正在使用大锤来破解螺母,所以我想我们不应该对它的速度更慢感到惊讶。保存正则表达式,以便在要查找的模式更复杂时使用。
您可能希望使用正则表达式的一种情况是,如果 并且不会完成这项工作,因为您只想匹配整个单词而不仅仅是子字符串,例如,您想要匹配但不匹配。正则表达式可以很好地处理这种情况,因为它们具有单词边界的概念。indexOf()
contains()
pear
spears
在这种情况下,我们将模式更改为:
\b(apple|orange|pear|banana|kiwi)\b
表示仅匹配单词的开头或结尾,括号将 OR 表达式组合在一起。\b
请注意,在代码中定义此模式时,您需要使用另一个反斜杠对反斜杠进行转义:
Pattern p = Pattern.compile("\\b(apple|orange|pear|banana|kiwi)\\b");
我不认为正则表达式在性能方面会做得更好,但你可以按如下方式使用它:
Pattern p = Pattern.compile("(apple|orange|pear)");
Matcher m = p.matcher(inputString);
while (m.find()) {
String matched = m.group(1);
// Do something
}