Ява. Игнорировать акценты при сравнении строк

Проблема проста. Есть ли какая-нибудь функция в JAVA для сравнения двух строк и возврата true, игнорируя акцентированные символы?

т

String x = "Joao";
String y = "João";

которые равны.

Спасибо

Ответ 1

Я думаю, вы должны использовать класс Collator. Он позволяет установить силу и локаль, и он будет соответствующим образом сравнивать символы.

Из API Java 1.6:

Вы можете установить силу Collator для определения уровня разница, значимая в сравнения. Четыре преимущества при условии: ПЕРВИЧНЫЙ, СРЕДНИЙ, ТЕРРИТОРИАЛЬНЫЙ и ИДЕНТИЧНЫЙ. Точный назначение сильных сторон языку функции зависят от локали. Для Например, на чешском языке "e" и "f" считаются первичными различиями, тогда как "e" и "ě" являются вторичными различиями, "e" и "E" - третичные различия и "e" и "e" идентичны.

Я думаю, что важный момент здесь (который люди пытаются сделать) состоит в том, что "Joao" и "João" никогда не должны считаться равными, но если вы делаете сортировку, вы не хотите, чтобы их сравнивали на основе их значение ASCII, потому что тогда у вас будет что-то вроде Joao, John, João, что плохо. Использование класса collator определенно корректно обрабатывает это.

Ответ 2

Вы не слышали об этом от меня (потому что я не согласен с предпосылкой вопроса), но вы можете использовать java.text.Normalizer и нормализовать с помощью NFD: это отделяет акцент от буквы, которую он прикрепляет к, Затем вы можете отфильтровать символы акцента и сравнить.

Ответ 3

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

public boolean isSame(String a, String b) {
    Collator insenstiveStringComparator = Collator.getInstance();
    insenstiveStringComparator.setStrength(Collator.PRIMARY);
    return insenstiveStringComparator.compare(a, b) == 0;
}

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

Ответ 4

Или используйте stripAccents из библиотеки Apache StringUtils, если вы хотите сравнивать/сортировать игнорируя акценты:

 public int compareStripAccent(String a, String b) {
    return StringUtils.stripAccents(a).compareTo(StringUtils.stripAccents(b));
}

Ответ 5

public boolean insenstiveStringComparator (String a, String b) {
    java.text.Collator collate = java.text.Collator.getInstance();
    collate.setStrength(java.text.Collator.PRIMARY);
    collate.setDecomposition(java.text.Collator.CANONICAL_DECOMPOSITION); 
    return collate.equals(a, b);    
}

Ответ 6

Проблема с подобными преобразованиями заключается в том, что не всегда есть четкое отображение от акцентированных к неадресным символам. Это зависит от кодовых страниц, локализации и т.д. Например, это а с акцентом, эквивалентным "а"? Не проблема для человека, но сложнее для компьютера.

AFAIK Java не имеет встроенного преобразования, которое может искать текущие параметры локализации и делать подобные преобразования. Возможно, вам понадобится внешняя библиотека, которая лучше обрабатывает юникод, например, ICU (http://site.icu-project.org/)