Frage

Wir haben ein System, bei dem Kunden, hauptsächlich Europäer, Texte (in UTF-8) eingeben, die an verschiedene Systeme verteilt werden müssen, von denen die meisten UTF-8 akzeptieren, aber jetzt müssen wir die Texte auch an ein US-System verteilen, das nur US akzeptiert -ASCII 7-Bit

Jetzt müssen wir also alle europäischen Zeichen in das nächstgelegene US-ASCII übersetzen.Gibt es Java-Bibliotheken, die bei dieser Aufgabe helfen?

Im Moment haben wir gerade damit begonnen, einer Übersetzungstabelle hinzuzufügen, wo Å (schwedisches AA)->A usw. ist, und wenn wir keine Übereinstimmung für ein eingegebenes Zeichen finden, protokollieren wir es und ersetzen es durch ein Fragezeichen und versuchen Sie, das für die nächste Version zu beheben, aber es scheint sehr ineffizient zu sein und jemand anderes muss zuvor etwas Ähnliches getan haben.

War es hilfreich?

Lösung

Der uni2ascii Das Programm ist in C geschrieben, aber Sie könnten es wahrscheinlich mit wenig Aufwand in Java konvertieren.Es enthält eine große Näherungstabelle (implizit in den Switch-Case-Anweisungen).

Beachten Sie, dass es keine allgemein akzeptierten Näherungen gibt:Die Deutschen möchten, dass Sie Ä durch AE ersetzen, Finnen und Schweden bevorzugen nur A.Ihr Beispiel für Å ist auch nicht offensichtlich:Schweden würden wahrscheinlich einfach den Ring fallen lassen und A verwenden, aber Dänen und Norwegern würde das historisch korrektere AA vielleicht besser gefallen.

Andere Tipps

Sie können dies tun, mit den folgenden (aus dem NFD Beispiel in diese Core-Java-Technologie Tech-Tipp ):

public static String decompose(String s) {
    return java.text.Normalizer.normalize(s, java.text.Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+","");
}

Statt Ihre eigene Tabelle zu erstellen, können Sie stattdessen den Text Normalisierungsform D konvertieren, wobei die Zeichen als Basiszeichen dargestellt werden und die diakritischen Zeichen (zum Beispiel „a“ wird durch „a“, gefolgt von einem ersetzt werden Kombinieren akut). Sie können dann alles abzustreifen, die kein ASCII Buchstaben ist.

Die Tabellen existieren noch, aber nun diejenigen sind, aus dem Unicode-Standard.

Sie können auch versuchen NFKD statt NFD, noch mehr Fälle zu fangen.

Referenzen:

Als Reaktion auf die von Joe Livers gegebene Antwort, die referenzierte Lucene ISOLatin1AccentFilter nicht mehr existiert :

Es wurde von org.apache.lucene.analysis.ASCIIFoldingFilter :

  

Diese Klasse konvertiert alphabetische, numerische und symbolische Unicode-Zeichen, die nicht in den ersten 127 ASCII-Zeichen (der „Basic Latin“ Unicode-Block) in ihre ASCII-Äquivalente sind, falls vorhanden. Zeichen aus den folgenden Blöcken Unicode umgewandelt werden; jedoch nur die Zeichen mit vernünftigen ASCII Alternativen umgesetzt werden.

FYI -

Dies ist typischerweise nützlich in Suchanwendungen. Siehe die entsprechenden Lucene ISOLatin1AccentFilter Umsetzung. Dies ist nicht wirklich entworfen, um in eine zufällige lokale Implementierung anschließen, aber den Trick funktioniert.

Es gibt einige Funktionen eingebaut, dies zu tun. Die Hauptklasse beteiligt ist CharsetEncoder , der Teil des Pakets ist nio. Ein einfacher Weg ist, String.getBytes(Charset) , dass auf ein

new String ( "½" .getBytes ( "US-ASCII"))

das ist, was ich benutze:

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

Dies ist, was zu funktionieren scheint:

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