Преобразуйте список слов в регулярное выражение, и пусть регулярное выражение выполнит поиск для вас.
Например, ваши 3 слова будут регулярным выражением, подобным следующему:
and|of|one
Конечно, вам не нужны частичные слова, поэтому вы бы добавили проверку границы слова:
\b(and|of|one)\b
Нет необходимости перехватывать слово (снова), так как все совпадение равно слову, поэтому используйте группу без захвата.Вы также можете легко сделать поиск слова нечувствительным к регистру.
Хотя с чистыми словами (всеми буквами) никогда не будет проблем, неплохо было бы охранять регулярное выражение, заключая слова в кавычки, используя Pattern.quote()
.
Пример
String doc = "one of the car and bike and one of those";
String[] words = { "and", "of", "one" };
// Build regex
StringJoiner joiner = new StringJoiner("|", "\\b(?:", ")\\b");
for (String word : words)
joiner.add(Pattern.quote(word));
String regex = joiner.toString();
// Find words
for (Matcher m = Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(doc); m.find(); )
System.out.println(m.group() + "-->" + m.start());
Выход
one-->0
of-->4
and-->15
and-->24
one-->28
of-->32
Если вы хотите сжать (скрыть)немного кодировать, вы можете написать это как один оператор в Java 9 +:
Pattern.compile(Stream.of(words).collect(joining("|", "(?i)\\b(?:", ")\\b"))).matcher(doc).results().forEach(r -> System.out.println(r.group() + "-->" + r.start()));
Вывод такой же.