Pergunta

O problema é que, como você sabe, existem milhares de caracteres em o Unicode gráfico e eu quero converter todos os personagens semelhantes às letras que são em Inglês alfabeto.

Por exemplo, aqui estão algumas conversões:

ҥ->H
Ѷ->V
Ȳ->Y
Ǭ->O
Ƈ->C
tђє Ŧค๓เℓy --> the Family
...

E vi que há mais de 20 versões de letra A / a. e eu não sei como classificá-los. Eles se parecem com agulhas no palheiro.

A lista completa de caracteres Unicode é em http: //www.ssec .wisc.edu / ~ tomw / java / unicode.html ou http://unicode.org /charts/charindex.html . Basta tentar rolar para baixo e ver as variações de letras.

Como posso converter todos estes com Java? Por favor me ajude: (

Foi útil?

Solução

Reposting meu post de Como eu diacríticos Remover (acentos) a partir de uma string em .NET?

Este método funciona bem em java (apenas para fins de remoção de sinais diacríticos aka acentos) .

É basicamente converte todos os caracteres acentuados em suas contrapartes deAccented seguido por seus sinais diacríticos que combinam. Agora você pode usar um regex para retirar os sinais diacríticos.

import java.text.Normalizer;
import java.util.regex.Pattern;

public String deAccent(String str) {
    String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD); 
    Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
    return pattern.matcher(nfdNormalizedString).replaceAll("");
}

Outras dicas

É uma parte de Apache Commons Lang como de ver. 3.0.

org.apache.commons.lang3.StringUtils.stripAccents("Añ");

retornos An

Veja também http: //www.drillio. com / en / software de desenvolvimento / java / removendo-acentos-diacríticos-em-qualquer-language /

A tentativa de "convertê-los todos" é a abordagem errada para o problema.

Em primeiro lugar, você precisa entender as limitações do que você está tentando fazer. Como outros apontaram, diacríticos estão lá por uma razão: eles são essencialmente letras originais do alfabeto de um idioma com seu próprio significado / som etc .: a remoção dessas marcas é exatamente o mesmo como a substituição de letras aleatórias em uma palavra em Inglês. Esta é antes mesmo de ir para considerar os idiomas cirílicos e outros textos de script baseado, como o árabe, que simplesmente não pode ser "convertido" para Inglês.

Se você deve , por qualquer motivo, personagens converter-se, então, a única maneira sensata de se aproximar isso para reduzir primeiramente o alcance da tarefa em mãos. Considere a fonte da entrada - se você está codificando um pedido de "mundo ocidental" (para uso como boa uma frase como qualquer), seria improvável que você poderia precisar para analisar caracteres árabes. Da mesma forma, o conjunto de caracteres Unicode contém centenas de símbolos matemáticos e pictóricas:. Não existe (fácil) maneira para os usuários a entrar diretamente estes, para que possa assumir que eles podem ser ignorados

Ao tomar estes passos lógicos que você pode reduzir o número de caracteres possíveis para analisar a um ponto em um dicionário baseado pesquisa / substituir operação é viável. Torna-se então uma pequena quantidade de chato ligeiramente trabalho criando os dicionários, e uma tarefa trivial para realizar a substituição. Se o seu idioma suporta caracteres nativos Unicode (como Java faz) e otimiza estruturas estáticas corretamente, tal achado e substitui tendem a ser incrivelmente rápida.

Esta vem da experiência de ter trabalhado em um aplicativo que foi necessário para permitir que os usuários finais para procurar dados bibliográficos que incluíam caracteres diacríticos. As matrizes de pesquisa (como era no nosso caso) teve talvez um dia o homem produzir, para cobrir todos os sinais diacríticos para todos os idiomas da Europa Ocidental.

Uma vez que a codificação que voltas "A Família" em "t?? T ? 3 ? ly" é efetivamente aleatória e não seguir qualquer algoritmo que pode ser explicado pela informação dos codepoints Unicode envolvidos, não há nenhuma maneira geral para resolver este algorithmically .

Você vai precisar para construir o mapeamento de caracteres Unicode em caracteres latinos que se assemelham. Você provavelmente poderia fazer isso com um pouco de aprendizado de máquina inteligente sobre os glifos reais que representam os codepoints Unicode. Mas eu acho que o esforço para isso seria maior do que construir manualmente o mapeamento. Especialmente se você tem uma boa quantidade de exemplos de que você pode construir o seu mapeamento.

Para esclarecer:. Algumas das substituições pode realmente ser resolvido através dos dados de Unicode (como as outras respostas demonstram), mas algumas cartas simplesmente não têm qualquer associação razoável com os caracteres latinos que se assemelham

Exemplos:

  • "?" (U + 0452 CYRILLIC letra pequena DJE) é mais relacionadas com "d" do que com "h", mas é usado para representar "h".
  • "T" (U + 0166 LATIN LETRA T com acidente vascular cerebral) é algo relacionado com "T" (como o nome sugere), mas é usado para representar "F".
  • "?" (U + 0E04 THAI PERSONAGEM KHO Khwai) não está relacionado com qualquer personagem Latina em tudo e no seu exemplo é usado para representar "a"

O pedido original foi já respondeu.

No entanto, estou postando a seguir resposta para aqueles que possam estar à procura de código transliteração genérico para transcrever qualquer charset para Latin / Inglês em Java.

significado Naive de tranliteration: Traduzido corda em sua sons charset forma / finais de destino como a corda na sua forma original. Se queremos transcrever qualquer charset para latinos (alfabeto inglês), então UTI4 (biblioteca ICU4J em java) irá fazer o trabalho.

Aqui está o trecho de código em Java:

    import com.ibm.icu.text.Transliterator; //ICU4J library import

    public static String TRANSLITERATE_ID = "NFD; Any-Latin; NFC";
    public static String NORMALIZE_ID = "NFD; [:Nonspacing Mark:] Remove; NFC";

    /**
    * Returns the transliterated string to convert any charset to latin.
    */
    public static String transliterate(String input) {
        Transliterator transliterator = Transliterator.getInstance(TRANSLITERATE_ID + "; " + NORMALIZE_ID);
        String result = transliterator.transliterate(input);
        return result;
    }

Se a necessidade é converter "òéisöç-> oeisoc", você pode usar esse ponto de partida:

public class AsciiUtils {
    private static final String PLAIN_ASCII =
      "AaEeIiOoUu"    // grave
    + "AaEeIiOoUuYy"  // acute
    + "AaEeIiOoUuYy"  // circumflex
    + "AaOoNn"        // tilde
    + "AaEeIiOoUuYy"  // umlaut
    + "Aa"            // ring
    + "Cc"            // cedilla
    + "OoUu"          // double acute
    ;

    private static final String UNICODE =
     "\u00C0\u00E0\u00C8\u00E8\u00CC\u00EC\u00D2\u00F2\u00D9\u00F9"             
    + "\u00C1\u00E1\u00C9\u00E9\u00CD\u00ED\u00D3\u00F3\u00DA\u00FA\u00DD\u00FD" 
    + "\u00C2\u00E2\u00CA\u00EA\u00CE\u00EE\u00D4\u00F4\u00DB\u00FB\u0176\u0177" 
    + "\u00C3\u00E3\u00D5\u00F5\u00D1\u00F1"
    + "\u00C4\u00E4\u00CB\u00EB\u00CF\u00EF\u00D6\u00F6\u00DC\u00FC\u0178\u00FF" 
    + "\u00C5\u00E5"                                                             
    + "\u00C7\u00E7" 
    + "\u0150\u0151\u0170\u0171" 
    ;

    // private constructor, can't be instanciated!
    private AsciiUtils() { }

    // remove accentued from a string and replace with ascii equivalent
    public static String convertNonAscii(String s) {
       if (s == null) return null;
       StringBuilder sb = new StringBuilder();
       int n = s.length();
       for (int i = 0; i < n; i++) {
          char c = s.charAt(i);
          int pos = UNICODE.indexOf(c);
          if (pos > -1){
              sb.append(PLAIN_ASCII.charAt(pos));
          }
          else {
              sb.append(c);
          }
       }
       return sb.toString();
    }

    public static void main(String args[]) {
       String s = 
         "The result : È,É,Ê,Ë,Û,Ù,Ï,Î,À,Â,Ô,è,é,ê,ë,û,ù,ï,î,à,â,ô,ç";
       System.out.println(AsciiUtils.convertNonAscii(s));
       // output : 
       // The result : E,E,E,E,U,U,I,I,A,A,O,e,e,e,e,u,u,i,i,a,a,o,c
    }
}

O JDK 1.6 fornece a classe java.text.Normalizer que pode ser usado para esta tarefa.

Veja um exemplo aqui

Cordas testado: ÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝß

Testado:

A última opção é a melhor.

Você pode tentar usar unidecode, que está disponível como um ruby ??gem e como perl módulo sobre cpan . Essencialmente, ele funciona como uma tabela de pesquisa enorme, onde cada ponto de código Unicode relaciona-se com um caractere ASCII ou string.

Não há nenhuma maneira fácil ou geral para fazer o que quiser, porque é apenas a sua opinião subjectiva que essas cartas procurar loke as letras latinas que você deseja converter. Eles são realmente cartas separadas com seus próprios nomes distintas e sons que só acontecerá a olhar superficialmente como uma carta latino.

Se você quiser que a conversão, você tem que criar sua própria tabela de conversão com base no que letras latinas você acha que as cartas não-latinos devem ser convertidos para.

(Se você só quer remover as marcas diacritial, existem algumas respostas neste tópico: Como faço para remover sinais diacríticos (acentos) a partir de uma string em .NET? no entanto você descreve um problema mais geral)

Eu estou atrasado para a festa, mas depois de enfrentar esta questão hoje, achei que esta resposta seja muito bom:

String asciiName = Normalizer.normalize(unicodeName, Normalizer.Form.NFD)
    .replaceAll("[^\\p{ASCII}]", "");

Referência: https://stackoverflow.com/a/16283863

O problema com "converter" arbitrária Unicode para ASCII é que o significado de um personagem é dependente da cultura. Por exemplo, “ß” para uma pessoa de língua alemã deve ser convertido para "ss", enquanto um alto-falante Inglês provavelmente convertê-lo para “B”.

Adicione a isso o fato de que Unicode tem vários pontos de código para os mesmos glifos.

O resultado é que a única maneira de fazer isso é criar uma tabela enorme com cada personagem Unicode eo carácter ASCII que você quer convertê-lo para. Você pode pegar um atalho por personagens normalizando com acentos a forma normalização KD, mas nem todos os personagens normalizar a ASCII. Além disso, Unicode não define quais partes de um glifo são "acentos".

Aqui está um pequeno trecho de um aplicativo que faz isso:

switch (c)
{
    case 'A':
    case '\u00C0':  //  À LATIN CAPITAL LETTER A WITH GRAVE
    case '\u00C1':  //  Á LATIN CAPITAL LETTER A WITH ACUTE
    case '\u00C2':  //  Â LATIN CAPITAL LETTER A WITH CIRCUMFLEX
    // and so on for about 20 lines...
        return "A";
        break;

    case '\u00C6'://  Æ LATIN CAPITAL LIGATURE AE
        return "AE";
        break;

    // And so on for pages...
}

A seguir classe faz o truque:

org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top