2010-03-03 6 views
48

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

т.е.

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

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

Благодаря

+7

, но это __NOT__ равно, почему вы хотите, чтобы они были равны, когда они не являются? –

+6

@fuzzy оба имеют одно и то же имя (это португальская версия для Джона).Некоторые люди просто ленивы, чтобы включить акценты –

+1

На испанском языке n и - считаются разными буквами. –

ответ

60

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

С Java 1.6 API:

Вы можете установить подборщик в свойство силы определить уровень разницы считается значимым в сравнениях. Четыре достоинства: : PRIMARY, SECONDARY, TERTIARY и IDENTICAL. Точные назначение сильных сторон языку функции зависят от локали. Для пример, на чешском языке, «e» и «f» являются , считаются основными отличиями, а «e» и «ě» являются вторичными отличиями, «e» и «E» являются третичными отличиями и «e» и «e» идентичны.

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

+1

Это лучший ответ, чем принятый. –

+3

@Software Monkey: Я тоже согласен, хотя я написал принятый ответ. :-P –

+1

Люди FYI, создали немного кода [здесь] (https://code.google.com/p/jjcommon/source/browse/trunk/src/main/java/com/jjcommon/JJStringUtils.java? spec = svn11 & r = 11 # 82), который следует вашим рекомендациям, поэтому благодарим за это. Однако я не видел способ сделать сравнение, которое не чувствительно к ACCENT, но CASE чувствительно, следуя правилам Collator ... я что-то пропустил? –

-1

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

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

+0

Java имеет это, он называется [Collater] (http://docs.oracle.com/javase/tutorial/i18n/text/locale.html) и специально создан для этой проблемы. –

23

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

+0

Спасибо, это то, что мне нужно. – framara

+4

Эти два шага объединены в один по StringUtils.stripAccents http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/StringUtils.html – cquezel

+1

Это очень актуально особенно в системах, которые должны сравнивать международные данные. 1 Возможно, очень немногие системы в мире справляются с чем-либо многоязычным. Дело в том, что в нижеследующих разделах упоминается, что даже у java есть некорректная поддержка Unicode. 2- Когда у вас есть услуги, которые принимают данные от третьих сторон, которые все идут по трубам. Поскольку никто никогда не обрабатывает данные последовательно. 2- Как уже упоминалось, люди просто не вводят данные должным образом. Либо потому, что ленивы, опечатки и т. Д. ... 3- Жоао может также быть испанским пользователем, к сожалению, используя английский компьютер. – user432024

4

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

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

isSame ("а", "А") дает истинное

2

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

public int compareStripAccent(String a, String b) { 
    return StringUtils.stripAccents(a).compareTo(StringUtils.stripAccents(b)); 
} 
Смежные вопросы