Question

Le problème est que, comme vous le savez, il existe des milliers de caractères in le graphique Unicode et je souhaite convertir tous les caractères similaires en lettres de l’alphabet anglais.

Par exemple, voici quelques conversions:

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

et j'ai vu qu'il y avait plus de 20 versions de la lettre A / a. et je ne sais pas comment les classer. Ils ressemblent à des aiguilles dans la botte de foin.

La liste complète des caractères Unicode est disponible à l'adresse http: //www.ssec. .wisc.edu / ~ tomw / java / unicode.html ou http://unicode.org /charts/charindex.html . Essayez simplement de faire défiler la liste et de voir les variations des lettres

Comment puis-je convertir tout cela avec Java? Aidez-moi s'il vous plaît: (

Était-ce utile?

La solution

Republier mon message de Comment puis-je supprimer les signes diacritiques (accents) d'une chaîne dans .NET?

Cette méthode fonctionne correctement en java (uniquement dans le but de supprimer les marques diacritiques, à savoir les accents) .

Il convertit fondamentalement tous les caractères accentués en leurs équivalents décents, suivis de la combinaison de leurs signes diacritiques. Vous pouvez maintenant utiliser une expression rationnelle pour éliminer les signes diacritiques.

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("");
}

Autres conseils

Cela fait partie de Apache Commons Lang à partir de ver. 3.0.

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

renvoie Un

Voir aussi http: //www.drillio. com / fr / développement-logiciel / java / removal-accents-diacritics-in-any-language /

Tentative de "conversion de tous" " est la mauvaise approche du problème.

Tout d’abord, vous devez comprendre les limites de ce que vous essayez de faire. Comme d'autres l'ont souligné, les signes diacritiques ont une raison: ils sont essentiellement des lettres uniques dans l'alphabet de cette langue, avec leur propre signification / son, etc.: supprimer ces marques revient à remplacer des lettres aléatoires dans un mot anglais. C’est avant même d’envisager les langues cyrilliques et d’autres textes basés sur des scripts tels que l’arabe, qui ne peuvent tout simplement pas être "convertis". vers l'anglais.

Si vous devez , pour une raison quelconque, convertir des caractères, le seul moyen sensé de l'aborder consiste à réduire en premier lieu l'étendue de la tâche à accomplir. Considérez la source de l'entrée - si vous codez une application pour "le monde occidental". (pour utiliser une phrase aussi bonne que toute autre phrase), il serait peu probable que vous ayez besoin d'analyser des caractères arabes. De même, le jeu de caractères Unicode contient des centaines de symboles mathématiques et picturaux: les utilisateurs ne peuvent pas (facilement) les saisir directement. Vous pouvez donc en déduire qu'ils peuvent être ignorés.

En prenant ces mesures logiques, vous pouvez réduire le nombre de caractères possibles à analyser jusqu'au point où une opération de recherche / remplacement basée sur un dictionnaire est réalisable. Cela devient alors une petite quantité de travail légèrement ennuyeux créant les dictionnaires, et une tâche triviale pour effectuer le remplacement. Si votre langue prend en charge les caractères Unicode natifs (comme Java) et optimise correctement les structures statiques, la recherche et le remplacement ont tendance à être extrêmement rapides.

Cela découle de l’expérience d’avoir travaillé sur une application nécessaire pour permettre aux utilisateurs finaux de rechercher des données bibliographiques contenant des caractères diacritiques. Les tableaux de recherche (comme dans notre cas) ont pris peut-être un jour de travail par jour pour couvrir tous les signes diacritiques de toutes les langues d'Europe occidentale.

Depuis l’encodage qui transforme "la famille" dans "t; ? ly" est effectivement aléatoire et ne suit aucun algorithme pouvant être expliqué par les informations des points de code Unicode impliqués, il n’existe aucun moyen général de résoudre cet algorithme.

Vous devrez créer le mappage des caractères Unicode en caractères latins auxquels ils ressemblent. Vous pouvez probablement le faire avec une machine intelligente à apprendre sur les glyphes représentant les points de code Unicode. Mais je pense que l'effort pour cela serait plus grand que de construire manuellement cette cartographie. Surtout si vous avez une bonne quantité d’exemples à partir desquels vous pouvez construire votre cartographie.

Pour clarifier: certaines des substitutions peuvent en réalité être résolues via les données Unicode (comme le montrent les autres réponses), mais certaines lettres n’ont tout simplement aucune association raisonnable avec les caractères latins auxquels elles ressemblent.

Exemples:

  • " ? " (U + 0452 LETTRE MINUSCULE CYRILLIQUE DJE) est plus lié à "d" que pour "h", mais est utilisé pour représenter "h".
  • " T " (U + 0166 LETTRE MAJUSCULE LATINE T AVEC COUP) est quelque peu liée à "T". (comme son nom l'indique) mais est utilisé pour représenter "F".
  • " ? " (U + 0E04 LE CARACTERE THAÏLANDAIS KHO KHWAI) n’est associé à aucun caractère latin et, dans votre exemple, il est utilisé pour représenter "un

La demande d'origine a déjà été traitée.

Cependant, je publie la réponse ci-dessous pour ceux qui recherchent un code de translittération générique pour translittérer tout jeu de caractères en latin / anglais en Java.

Sens naïf de la traduction: La chaîne traduite dans sa forme finale / le jeu de caractères cible ressemble à la chaîne dans sa forme originale. Si nous voulons translittérer n'importe quel jeu de caractères en latin (alphabets anglais), alors ICU4 (bibliothèque ICU4J en java) fera l'affaire.

Voici l'extrait de code en 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;
    }

Si le besoin est de convertir "òéisöç- > oeisoc", vous pouvez l'utiliser comme point de départ:

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
    }
}

Le JDK 1.6 fournit la classe java.text.Normalizer qui peut être utilisée pour cette tâche.

Voir un exemple ici

Chaîne testée: & # 193; & # 194; & # 195; & # 196; & # 197; & # 198; & # 199; & # 200; & # 201; & # 202; & # 203; & # 204; & # 205; & # 206; & # 207; & # 208; & # 209; & # 210; & # 211; & # 212; & # 213; & # 214; & # 216; & # 216; & ### 217; & # 218; & # 219; & # 220; & # 221; & # 223;

.

Testé:

  • Résultat de Apache Commons Lang3 : AAAAA & # 198; CEEEEIIII & # 208; NOOOOO & # 216; UUUUY & # 223;
  • Résultat de ICU4j : AAAAA & # 198; CEEEEIIII & # 208; NOOOOO & # 216; UUUUY & # 223;
  • Sortie de JUnidecode : AAAAAAECEEEEIDIDOOOOOUOUUUUss (problème avec & # 221; et un autre issue )
  • Sortie de code Unidecode : AAAAAAECEEEE IIIIDNOOOOOOUUUUUYU

Le dernier choix est le meilleur.

Vous pouvez essayer d’utiliser unidecode , disponible sous forme de gem ruby ?? et en tant que module perl sur cpan . Pour l’essentiel, cela fonctionne comme une énorme table de correspondance, où chaque point de code unicode se rapporte à un caractère ou une chaîne ascii.

Il n’existe aucun moyen simple ni général de faire ce que vous voulez, c’est votre opinion subjective que ces lettres ressemblent aux lettres latines que vous voulez convertir. Ce sont en fait des lettres séparées avec leurs propres noms et sons distincts qui ressemblent superficiellement à une lettre latine.

Si vous souhaitez cette conversion, vous devez créer votre propre table de traduction en fonction des lettres latines auxquelles vous pensez que les lettres non latines doivent être converties.

(Si vous souhaitez uniquement supprimer les marques diacritiales, il existe des réponses à cette discussion: Comment puis-je supprimer les signes diacritiques (accents) d'une chaîne dans .NET? Toutefois, vous décrivez un problème plus général)

Je suis en retard au parti, mais après avoir affronté ce problème aujourd'hui, j'ai trouvé cette réponse très bonne:

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

Référence: https://stackoverflow.com/a/16283863

Problème lié à la conversion; Unicode arbitraire en ASCII signifie que la signification d’un caractère dépend de la culture. Par exemple, «ß» pour une personne de langue allemande doit être converti en "ss". alors qu'un anglophone le convertirait probablement en «B».

Ajoutez à cela le fait qu'Unicode possède plusieurs points de code pour les mêmes glyphes.

Le résultat est que le seul moyen de le faire est de créer une table volumineuse avec chaque caractère Unicode et le caractère ASCII que vous souhaitez convertir. Vous pouvez utiliser un raccourci en normalisant les caractères accentués à la normalisation KD, mais tous les caractères ne normalisent pas en ASCII. De plus, Unicode ne définit pas les parties d’un glyphe qui sont des "accents".

Voici un petit extrait d'une application qui fait ceci:

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...
}

Suivre la classe fait le tour:

org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top