Замена символа пресечения юникода на ASCII-аппроксимации

Я читаю некоторые текстовые файлы в программе Java и хотел бы заменить некоторые символы Unicode на ASCII-приближения. Эти файлы в конечном итоге будут разбиты на предложения, которые подаются в OpenNLP. OpenNLP не распознает символы Юникода и дает неправильные результаты по ряду символов (он символизирует «девушку» как «девушка» и «с», но если это котировка Юникода, она рассматривается как один токен).

Например, исходное предложение может содержать направленную котировку Unicode U2018 (‘), и я хотел бы преобразовать ее в U0027 (‘). В конце концов я удалю оставшийся Unicode.

Я понимаю, что теряю информацию, и я знаю, что могу писать регулярные выражения для преобразования каждого из этих символов, но я спрашиваю, есть ли код, который я могу повторно использовать, чтобы преобразовать некоторые из этих символов.

Это то, что я мог, но я уверен, что буду совершать ошибки / пропустить вещи / etc .:

// double quotation (") replacements.add(new Replacement(Pattern.compile("[\u201c\u201d\u201e\u201f\u275d\u275e]"), "\"")); // single quotation (') replacements.add(new Replacement(Pattern.compile("[\u2018\u2019\u201a\u201b\u275b\u275c]"), "'")); 

замены – это особый class, который я позже запускаю и применяю замены.

  for (Replacement replacement : replacements) { text = replacement.pattern.matcher(text).replaceAll(r.replacement); } 

Как вы можете видеть, мне пришлось найти:

  • ЛЕВАЯ ОДНОМЕСТНАЯ ЦЕНА
  • ПРАВИЛЬНАЯ ОДНОЦВЕТНАЯ МАРКА
  • SINGLE LOW-9 QUOTATION MARK (что это / следует заменить?)
  • ОДИНОЧНАЯ ВЫСОКАЯ-ПЕРЕСМОТРЕННАЯ-9 ЦИТАТА (что это / следует заменить?)

Каждому символу юникода присваивается категория . Для кавычек существует две отдельные категории:

  • Пунктуация, Окончательная цитата (может вести себя как Ps или Pe в зависимости от использования)
  • Пунктуация, Начальная цитата (может вести себя как Ps или Pe в зависимости от использования)

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

Java Character.getType дает вам категорию символов, например FINAL_QUOTE_PUNCTUATION .

Теперь вы можете получить категорию каждого (символ пунктуации) и заменить ее соответствующим дополнением в ASCII.

Вы можете использовать другие знаки препинания. В «Пунктуация, другое» есть некоторые символы, например PRIME , которые вы также можете заменить апострофом.

Я нашел довольно обширную таблицу, которая отображает пунктуацию Unicode в их ближайших эквивалентах ASCII .

Вот еще информация: Символы карты и знаки препинания для ASCII .

Я следил за ссылкой @ marek-stoj и создал приложение Scala, которое очищает unicode от строк при сохранении длины строки. Он удаляет диакритические знаки (акценты) и использует карту, предложенную @ marek-stoj, для преобразования символов Unicode без Ascii в их приближения ascii.

 import java.text.Normalizer object Asciifier { def apply(string: String) = { var cleaned = string for ((unicode, ascii) <- substitutions) { cleaned = cleaned.replaceAll(unicode, ascii) } // convert diacritics to a two-character form (NFD) // http://docs.oracle.com/javase/tutorial/i18n/text/normalizerapi.html cleaned = Normalizer.normalize(cleaned, Normalizer.Form.NFD) // remove all characters that combine with the previous character // to form a diacritic. Also remove control characters. // http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html cleaned.replaceAll("[\\p{InCombiningDiacriticalMarks}\\p{Cntrl}]", "") // size must not change require(cleaned.size == string.size) cleaned } val substitutions = Set( (0x00AB, '"'), (0x00AD, '-'), (0x00B4, '\''), (0x00BB, '"'), (0x00F7, '/'), (0x01C0, '|'), (0x01C3, '!'), (0x02B9, '\''), (0x02BA, '"'), (0x02BC, '\''), (0x02C4, '^'), (0x02C6, '^'), (0x02C8, '\''), (0x02CB, '`'), (0x02CD, '_'), (0x02DC, '~'), (0x0300, '`'), (0x0301, '\''), (0x0302, '^'), (0x0303, '~'), (0x030B, '"'), (0x030E, '"'), (0x0331, '_'), (0x0332, '_'), (0x0338, '/'), (0x0589, ':'), (0x05C0, '|'), (0x05C3, ':'), (0x066A, '%'), (0x066D, '*'), (0x200B, ' '), (0x2010, '-'), (0x2011, '-'), (0x2012, '-'), (0x2013, '-'), (0x2014, '-'), (0x2015, '-'), (0x2016, '|'), (0x2017, '_'), (0x2018, '\''), (0x2019, '\''), (0x201A, ','), (0x201B, '\''), (0x201C, '"'), (0x201D, '"'), (0x201E, '"'), (0x201F, '"'), (0x2032, '\''), (0x2033, '"'), (0x2034, '\''), (0x2035, '`'), (0x2036, '"'), (0x2037, '\''), (0x2038, '^'), (0x2039, '<'), (0x203A, '>'), (0x203D, '?'), (0x2044, '/'), (0x204E, '*'), (0x2052, '%'), (0x2053, '~'), (0x2060, ' '), (0x20E5, '\\'), (0x2212, '-'), (0x2215, '/'), (0x2216, '\\'), (0x2217, '*'), (0x2223, '|'), (0x2236, ':'), (0x223C, '~'), (0x2264, '<'), (0x2265, '>'), (0x2266, '<'), (0x2267, '>'), (0x2303, '^'), (0x2329, '<'), (0x232A, '>'), (0x266F, '#'), (0x2731, '*'), (0x2758, '|'), (0x2762, '!'), (0x27E6, '['), (0x27E8, '<'), (0x27E9, '>'), (0x2983, '{'), (0x2984, '}'), (0x3003, '"'), (0x3008, '<'), (0x3009, '>'), (0x301B, ']'), (0x301C, '~'), (0x301D, '"'), (0x301E, '"'), (0xFEFF, ' ')).map { case (unicode, ascii) => (unicode.toChar.toString, ascii.toString) } } 

Хотя это точно не отвечает на ваш вопрос, вы можете преобразовать текст в Unicode в US-ASCII, заменяя символы, отличные от ASCII, на «?» символы.

 String input = "aáeéiíoóuú"; // 10 chars. Charset ch = Charset.forName("US-ASCII"); CharsetEncoder enc = ch.newEncoder(); enc.onUnmappableCharacter(CodingErrorAction.REPLACE); enc.replaceWith(new byte[]{'?'}); ByteBuffer out = null; try { out = enc.encode(CharBuffer.wrap(input)); } catch (CharacterCodingException e) { /* ignored, shouldn't happen */ } String outStr = ch.decode(out).toString(); // Prints "a?e?i?o?u?" System.out.println(outStr); 

То, что я сделал для подобных подстановок, – это создать Map (обычно HashMap ) с символами Unicode в качестве ключей и их заменять значениями.

Псевдо-Java; for зависит от того, какой контейнер символов вы используете в качестве параметра для метода, который делает это, например String, CharSequence и т. д.

 StringBuilder output = new StringBuilder(); for (each Character 'c' in inputString) { Character replacement = xlateMap.get( c ); output.append( replacement != null ? replacement : c ); } return output.toString(); 

Все, что находится на Карте, заменено, все, что не на карте, не изменяется и копируется для вывода.

Вот пакет Python, который делает хорошую работу. Он основан на модуле Perl Text :: Unidecode. Я предполагаю, что это можно портировать на Java.

http://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/

http://pypi.python.org/pypi/Unidecode

  • Преобразование строки Unicode в экранированную строку ASCII
  • iconv: Преобразование из Windows ANSI в UTF-8 с помощью спецификации
  • В Unicode, почему существуют два представления для арабских цифр?
  • Как сделать Quick Look предварительным просмотром текстовых файлов в UTF-8 по умолчанию?
  • Как сделать python 3 print () utf8
  • Как я могу ввести символ U + 200B?
  • В чем разница между _tmain () и main () в C ++?
  • Как скомпилировать исходный файл java, который кодируется как «UTF-8»?
  • Что такое «суррогатная пара» на Java?
  • Значок воспроизведения Unicode ▶ отображается в заголовке страницы, неправильно отображается в моем браузере Firefox
  • Кодировка Unicode для строковых литералов в C ++ 11
  • Interesting Posts

    Excel VBA циклически перемещается по нескольким листам

    создание пользовательских ячеек таблицы в быстрых

    Кэширование изображений в Интернете

    Как сделать кодировку Base64 в node.js?

    В Java Swing, как вы получаете ссылку на дескриптор windows Win32 (hwnd) на окно?

    Найден один или несколько многократно определенных символов

    Можно ли установить тайм-аут для std :: cin?

    Можем ли мы предположить значения массива по умолчанию в Java? например, предположим, что массив int задан для всех нhive?

    Powershell Get-ChildItem Include \ Exclude – простой скрипт не работает должным образом

    Как записывать как Mic Audio, так и динамики при использовании гарнитуры

    Преобразование традиционного частного ключа PEM в закрытый ключ PKCS8

    API Android Google Maps v2 – Интерактивный InfoWindow (как в оригинальных картах Google Android)

    Почему сброс ADSL-модема настолько эффективен?

    Как преобразовать String в ArrayList?

    Отображение нескольких аннотаций в MKMapView

    Давайте будем гением компьютера.