Для поиска букв / цифр в указанном порядке, игнорируя прописные и строчные буквы, пробелы и специальные символы, лучше всего преобразовать строку поиска в регулярное выражение .
Чтобы строка поиска "foobar"
соответствовала "Foo-Bar"
, нам нужно разрешить специальные символы между любыми буквенными символами c символов.
Для полной поддержки Unicode мы будем использовать \p{Alnum}
и флаги UNICODE_CHARACTER_CLASS
, CASE_INSENSITIVE
и UNICODE_CASE
или, скорее, заглавные буквы P
для не алфавита.
Чтобы сопоставить, например, A
с Á
, мы также разлагаем символы Юникода, используя Normalizer.normalize(str, Normalizer.Form.NFD)
.
Вот Пример того, как это сделать:
static List<String> search(List<String> texts, String word) {
String regex = Normalizer.normalize(word, Normalizer.Form.NFD) // e.g. "Á" -> "A\u0301"
.replaceAll("(?U)\\P{Alnum}+", "") // e.g. "I'm!" -> "Im"
.replaceAll("(?<=.)(?=.)", "\\\\P{Alnum}*"); // insert '\\P{Alnum}*' between all characters
Pattern p = Pattern.compile(regex, Pattern.UNICODE_CHARACTER_CLASS |
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
List<String> trueOnes = new ArrayList<>();
for (String text : texts) {
if (p.matcher(Normalizer.normalize(text, Normalizer.Form.NFD)).find()) {
trueOnes.add(text);
}
}
return trueOnes;
}
Тесты
List<String> texts = List.of("Homemade Pizza!", "Dessert", "Pizza Hut", "Potato-Söûp", "O'Malleys Ale");
System.out.println(search(texts, "pizza")); // [Homemade Pizza!, Pizza Hut]
System.out.println(search(texts, "made, pi")); // [Homemade Pizza!]
System.out.println(search(texts, "ömÁl")); // [O'Malleys Ale]
System.out.println(search(texts, "TOSO")); // [Potato-Söûp]