Comment convertir UTF-8 en US-Ascii en Java
Question
Nous avons un système dans lequel les clients, principalement européens, saisissent des textes (en UTF-8) qui doivent être distribués vers différents systèmes, la plupart acceptant UTF-8, mais nous devons maintenant les distribuer également vers un système américain. accepte uniquement l'US-Ascii 7-bit
Nous allons maintenant devoir traduire tous les caractères européens vers l'US-Ascii le plus proche. Existe-t-il des bibliothèques Java pour vous aider dans cette tâche?
Nous venons tout juste de commencer l’ajout à une table de traduction, où & # 197; (suédois AA) - > A et ainsi de suite et si nous ne trouvons aucune correspondance pour un caractère saisi, nous le consignerons et le remplacerons par un point d'interrogation et essayerons de le corriger pour la prochaine version, mais cela semble très inefficace et quelqu'un d'autre doit avoir fait quelque chose de similaire avant.
La solution
Le programme uni2ascii est écrit en C, mais vous pouvez probablement le convertir en Java avec peu effort. Il contient une grande table d’approximations (implicitement, dans les instructions switch-case).
Sachez qu’il n’ya pas d’approche universellement acceptée: les Allemands veulent que vous remplaciez & # 196; par AE, les Finlandais et les Suédois préfèrent simplement A. Votre exemple de & # 197; isn Et ce n’est pas évident non plus: les Suédois abandonneraient probablement l’anneau et utiliseraient A, mais les Danois et les Norvégiens aimeraient mieux les AA historiquement plus corrects.
Autres conseils
Vous pouvez le faire avec les éléments suivants (à partir de l'exemple NFD dans ce conseil technique relatif aux technologies Java de base ):
public static String decompose(String s) {
return java.text.Normalizer.normalize(s, java.text.Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+","");
}
Au lieu de créer votre propre table, vous pouvez convertir le texte en formulaire de normalisation D, où les caractères sont représentés par un caractère de base plus les signes diacritiques (par exemple, "& # 225;" sera remplacé par ; a "suivi d'un accent aigu combinant). Vous pouvez alors supprimer tout ce qui n’est pas une lettre ASCII.
Les tables existent toujours, mais sont maintenant celles du standard Unicode.
Vous pouvez également essayer NFKD au lieu de NFD, pour attraper encore plus de cas.
Références:
En réponse à la réponse donnée par Joe Liversedge , la référence Lucene ISOLatin1AccentFilter n'existe plus :
Il a été remplacé par org.apache.lucene.analysis.ASCIIFoldingFilter :
Cette classe convertit les caractères Unicode alphabétiques, numériques et symboliques qui ne figurent pas dans les 127 premiers caractères ASCII (le bloc Unicode "Basic Latin") en leurs équivalents ASCII, le cas échéant. Les caractères des blocs Unicode suivants sont convertis. cependant, seuls les caractères avec des alternatives ASCII raisonnables sont convertis.
FYI -
Ceci est généralement utile dans les applications de recherche. Voir les ISOLatin1AccentFilter <> / a> implémentation. Ce n’est pas vraiment conçu pour être connecté à une implémentation locale aléatoire, mais fait le tour.
Certaines fonctions intégrées permettent de faire cela. La principale classe impliquée est CharsetEncoder
, qui fait partie du package nio
. Une méthode plus simple est String.getBytes (Charset)
pouvant être envoyé à un ByteArrayOutputStream
.
new String ("& # 189;" .getBytes ("US-ASCII"))
c'est ce que j'utilise:
<?php
function remove_accent($str) {
# http://www.php.net/manual/en/function.preg-replace.php#96586
$a = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', 'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', 'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ', 'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', 'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', 'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', 'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ', 'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', 'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', 'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ');
$b = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
return str_replace($a, $b, $str);
}
function SEOify($i){
# http://php.ca/manual/en/function.preg-replace.php#90316
$o = $i;
$o = html_entity_decode($o,ENT_COMPAT,'UTF-8');
$o = remove_accent(trim($o));
$patterns = array( "([\40])" , "([^a-zA-Z0-9_-])", "(-{2,})" );
$replacers = array("-", "", "-");
$o = preg_replace($patterns, $replacers, $o);
return $o;
}
?>
Voici ce qui semble fonctionner:
private synchronized static String utftoasci(String s){
final StringBuffer sb = new StringBuffer( s.length() * 2 );
final StringCharacterIterator iterator = new StringCharacterIterator( s );
char ch = iterator.current();
while( ch != StringCharacterIterator.DONE ){
if(Character.getNumericValue(ch)>0){
sb.append( ch );
}else{
boolean f=false;
if(Character.toString(ch).equals("Ê")){sb.append("E");f=true;}
if(Character.toString(ch).equals("È")){sb.append("E");f=true;}
if(Character.toString(ch).equals("ë")){sb.append("e");f=true;}
if(Character.toString(ch).equals("é")){sb.append("e");f=true;}
if(Character.toString(ch).equals("è")){sb.append("e");f=true;}
if(Character.toString(ch).equals("è")){sb.append("e");f=true;}
if(Character.toString(ch).equals("Â")){sb.append("A");f=true;}
if(Character.toString(ch).equals("ä")){sb.append("a");f=true;}
if(Character.toString(ch).equals("ß")){sb.append("ss");f=true;}
if(Character.toString(ch).equals("Ç")){sb.append("C");f=true;}
if(Character.toString(ch).equals("Ö")){sb.append("O");f=true;}
if(Character.toString(ch).equals("º")){sb.append("");f=true;}
if(Character.toString(ch).equals("Ó")){sb.append("O");f=true;}
if(Character.toString(ch).equals("ª")){sb.append("");f=true;}
if(Character.toString(ch).equals("º")){sb.append("");f=true;}
if(Character.toString(ch).equals("Ñ")){sb.append("N");f=true;}
if(Character.toString(ch).equals("É")){sb.append("E");f=true;}
if(Character.toString(ch).equals("Ä")){sb.append("A");f=true;}
if(Character.toString(ch).equals("Å")){sb.append("A");f=true;}
if(Character.toString(ch).equals("ä")){sb.append("a");f=true;}
if(Character.toString(ch).equals("Ü")){sb.append("U");f=true;}
if(Character.toString(ch).equals("ö")){sb.append("o");f=true;}
if(Character.toString(ch).equals("ü")){sb.append("u");f=true;}
if(Character.toString(ch).equals("á")){sb.append("a");f=true;}
if(Character.toString(ch).equals("Ó")){sb.append("O");f=true;}
if(Character.toString(ch).equals("É")){sb.append("E");f=true;}
if(!f){
sb.append("?");
}
}
ch = iterator.next();
}
return sb.toString();
}