Поиск строки Java без учета акцентов

Я пытаюсь написать функцию фильтра для своего приложения, которое будет принимать входную строку и отфильтровывать все объекты, которые каким-либо образом не соответствуют заданному входу. Самый простой способ сделать это - использовать метод String contains, т.е. просто проверить, содержит ли объект (переменная String в объекте) строку, указанную в фильтре, но при этом не будут учитываться акценты.

Рассматриваемые объекты - это в основном люди, а строки, которые я пытаюсь сопоставить, - это имена. Так, например, если кто-то ищет Joao, я ожидаю, что Joáo будет включен в набор результатов. Я уже использовал класс Collator в своем приложении для сортировки по имени, и он хорошо работает, потому что может сравнивать, то есть использование UK Locale á идет до b, но после a. Но очевидно, что он не возвращает 0, если вы сравниваете a и á, потому что они не равны.

Кто-нибудь знает, как я могу это сделать?


person DaveJohnston    schedule 07.03.2010    source источник
comment
Возможный дубликат Java. Игнорировать акценты при сравнении строк   -  person Barett    schedule 01.11.2016


Ответы (3)


Воспользуйтесь java.text.Normalizer и выстрелом из регулярного выражения. чтобы избавиться от диакритических знаков.

public static String removeDiacriticalMarks(String string) {
    return Normalizer.normalize(string, Form.NFD)
        .replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
}

Что вы можете использовать следующим образом:

String value = "Joáo";
String comparisonMaterial = removeDiacriticalMarks(value); // Joao
person BalusC    schedule 07.03.2010
comment
Я снимаю свой ответ! Никогда не сталкивался с java.text.Normalizer, спасибо за подсказку - person brabster; 07.03.2010
comment
Отлично. Я пытался выполнить совпадение регулярных выражений для строк, отличных от ascii, хотя и безуспешно. Нормализация кажется лучшим способом сделать это. - person ankimal; 24.06.2010
comment
Это плохой ответ. Вам необходимо использовать класс ICU Collator для создания объекта сопоставления с силой сравнения установлен на ПЕРВИЧНЫЙ. В этом ответе показано, как это сделать с точки зрения Perl. - person tchrist; 05.03.2011
comment
Здорово. Именно то, что я искал. Спасибо! - person Pablo Alba; 26.04.2011
comment
stackoverflow.com/questions/10812051 / - person mark; 30.05.2012
comment
Collator нельзя использовать для поиска в строке, только для сравнения полной строки, не работает в случае поиска (ожидайте точного совпадения!) Нормализатор работает хорошо, но работает медленно, подходит для одного значения, но не для поиска среди большой набор значений. - person RiRomain; 26.01.2018

Collator действительно возвращает 0 для a и á, если вы настроили его на игнорирование диакритических знаков:

public boolean isSame(String a, String b) {
    Collator insenstiveStringComparator = Collator.getInstance();
    insenstiveStringComparator.setStrength(Collator.PRIMARY);
    // Collator.PRIMARY also works, but is case senstive
    return insenstiveStringComparator.compare(a, b) == 0;
}

isSame ("a", "á") теперь дает true

person Benny Bottema    schedule 19.10.2016
comment
Это соответствует только точным эквивалентным строкам, но если вы хотите использовать содержит, это не сработает. - person Alejandro Cumpa; 08.09.2018

Я написал класс для поиска по арабским текстам, игнорируя диакритические знаки (НЕ удаляя их). может быть, вам удастся понять эту идею или как-то ее использовать.

DiacriticInsensitiveSearch.java

person mehdok    schedule 19.07.2017