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
Очевидно, что время будет варьироваться в зависимости от количества слов, в которых выполняется поиск, и строк, в которых выполняется поиск, но contains()
, кажется, в 10 раз быстрее, чем регулярные выражения для простого поиска, подобного этому.
Используя регулярные выражения для поиска строк внутри другой строки, вы используете кувалду, чтобы расколоть орех, так что я думаю, мы не должны удивляться, что он медленнее. Сохраняйте регулярные выражения для случаев, когда шаблоны, которые вы хотите найти, являются более сложными.
Один из случаев, когда вы можете захотеть использовать регулярные выражения, это если indexOf()
и contains()
не будут выполнять эту работу, потому что вы хотите сопоставлять только целые слова , а не только подстроки, например. Вы хотите соответствовать pear
, но не spears
. Регулярные выражения хорошо справляются с этим делом, так как имеют понятие границы слова .
В этом случае мы изменили бы наш шаблон на:
\b(apple|orange|pear|banana|kiwi)\b
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *.
Обратите внимание, что при определении этого шаблона в вашем коде необходимо избегать обратной косой черты с помощью другой обратной косой черты:
Pattern p = Pattern.compile("\\b(apple|orange|pear|banana|kiwi)\\b");