Как преобразовать UTF-8 в US-Ascii в Java

У нас есть система, в которой клиенты, в основном европейцы, вводят тексты (в UTF-8), которые должны быть распределены по разным системам, большинство из которых принимают UTF-8, но теперь мы также должны распространять тексты в систему США, которая принимает только США. -Ascii 7-битный

Итак, теперь нам нужно перевести все европейские символы в ближайший US-Ascii. Есть ли какие-нибудь библиотеки Java, которые помогут с этой задачей?

Прямо сейчас мы только начали добавлять в таблицу перевода, где Å (шведский AA) -> A и так далее, и где мы не находим совпадения для введенного символа, мы зарегистрируем его и заменим знаком вопроса и попытайтесь исправить это в следующем выпуске, но это кажется очень неэффективным, и кто-то другой, должно быть, делал что-то подобное раньше.

возможный дубликат Преобразование кодировки в java

kamaci 26.08.2012 17:38

Вы нашли решение? Я имею в виду, что это было 11 лет назад, но может быть?

Markus G. 30.04.2019 16:33

Мы создали нашу собственную таблицу сопоставления, далеко не полную, но удовлетворившую наши потребности.

Ulf Lindback 02.05.2019 07:52
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
27
3
56 613
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Для этого есть несколько встроенных функций. Основной задействованный класс - это CharsetEncoder, который является частью пакета nio. Более простой способ - это String.getBytes(Charset), который может быть отправлен на ByteArrayOutputStream.

Это не касается нормализации от «é» до «e».

Joe Liversedge 13.11.2008 03:10
Ответ принят как подходящий

Программа uni2ascii написана на C, но вы, вероятно, сможете преобразовать ее в Java без особых усилий. Он содержит большую таблицу приближений (неявно, в операторах switch-case).

Имейте в виду, что не существует общепринятых приближений: немцы хотят, чтобы вы заменили Ä на AE, финны и шведы предпочитают только A. Ваш пример Å также неочевиден: шведы, вероятно, просто отказались бы от кольца и использовали бы A, но датчане и Норвежцам могло бы больше понравиться исторически более правильное АА.

Отличные примеры региональных различий.

Tom Blodget 24.06.2015 03:33

Вместо того, чтобы создавать свою собственную таблицу, вы могли бы вместо этого преобразовать текст в форму нормализации D, где символы представлены как базовый символ плюс диакритические знаки (например, «á» будет заменено на «a» с последующим комбинированным острым ударением. ). Затем вы можете удалить все, что не является буквой ASCII.

Таблицы все еще существуют, но теперь они соответствуют стандарту Unicode.

Вы также можете попробовать NFKD вместо NFD, чтобы поймать еще больше случаев.

Использованная литература:

Связанный ответ: stackoverflow.com/questions/225471/…

CesarB 13.11.2008 02:25

Обычно это полезно в поисковых приложениях. См. Соответствующую реализацию Lucene ISOLatin1AccentFilter. На самом деле это не предназначено для включения в случайную локальную реализацию, но помогает.

Вот что вроде работает:

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

Вы можете сделать это следующим образом (из примера NFD в этот технический совет по основным технологиям Java):

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

NB: В scala это будет: def decopose (s: String): String = java.text.Normalizer.normalize (s, java.text.Normalizer.Form.NFD) .replaceAll ("\\ p {InCombiningDi‌ acriticalMarks} + "," ")

Jay Taylor 02.02.2012 02:45

вот что я использую:

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

новая строка ("½" .getBytes ("US-ASCII"))

В ответ на ответ, данный Джо Ливерседжем указанный Lucene ISOLatin1AccentFilterбольше не существует:

Он был заменен на org.apache.lucene.analysis.ASCIIFoldingFilter:

This class converts alphabetic, numeric, and symbolic Unicode characters which are not in the first 127 ASCII characters (the "Basic Latin" Unicode block) into their ASCII equivalents, if one exists. Characters from the following Unicode blocks are converted; however, only those characters with reasonable ASCII alternatives are converted.

К вашему сведению -

Другие вопросы по теме