son simbolos que los lista historia diferencias definicion como codigo codifica caracteres java unicode ascii

java - simbolos - Reemplazo de la puntuación de Unicode con aproximaciones ASCII



simbolos html unicode (6)

Estoy leyendo algunos archivos de texto en un programa Java y me gustaría reemplazar algunos caracteres Unicode con aproximaciones ASCII. Estos archivos finalmente se dividirán en oraciones que se envían a OpenNLP. OpenNLP no reconoce los caracteres Unicode y da resultados impropios en una serie de símbolos (simboliza "girl''s" como "girl" y "''s", pero si es una cita de Unicode, se trata como un token único) ..

Por ejemplo, la oración de origen puede contener la cita direccional de Unicode U2018 ('') y me gustaría convertirla en U0027 (''). Eventualmente voy a eliminar el resto de Unicode.

Entiendo que estoy perdiendo información y que puedo escribir expresiones regulares para convertir cada uno de estos símbolos, pero estoy preguntando si hay un código que pueda reutilizar para convertir algunos de estos símbolos.

Esto es lo que pude, pero estoy seguro de que cometeré errores / extrañaré cosas / 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]"), "''"));

reemplazos es una clase personalizada que luego ejecuto y aplico los reemplazos.

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

Como puedes ver, tuve que encontrar:

  • CITA ÚNICA DE LA IZQUIERDA
  • CITA ÚNICA A LA DERECHA
  • UNA SOLA MARCA DE COMUNICACIÓN DE LOW-9 (¿qué es esto / debería reemplazarlo?)
  • LISTA DE COMUNICACIÓN DE ALTO INVERTIDO AL 9 (¿qué es esto / debería reemplazarlo?)

A cada personaje Unicode se le asigna una category . Existen dos categorías separadas para las citas:

Con estas listas, debería poder manejar todas las citas de manera adecuada, si desea codificar la expresión regular de forma manual.

Java Character.getType te da la categoría de caracteres, por ejemplo FINAL_QUOTE_PUNCTUATION .

Ahora puede obtener la categoría de cada carácter (puntuación) y reemplazarlo con un suplemento apropiado en ASCII.

Puede utilizar las otras categorías de puntuación en consecuencia. En "Puntuación, Otros" hay algunos caracteres, por ejemplo PRIME , que también puede sustituir con un apóstrofe.




Lo que he hecho para sustituciones similares es crear un Map (generalmente HashMap ) con los caracteres Unicode como claves y su sustituto como valores.

Pseudo-java; el for depende del tipo de contenedor de caracteres que esté utilizando como parámetro del método que realiza esto, por ejemplo, String, CharSequence, etc.

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

Cualquier cosa en el mapa se reemplaza, cualquier cosa que no esté en el mapa no se modifica y se copia en la salida.


Seguí el enlace de @ marek-stoj y creé una aplicación de Scala que limpia unicode de las cadenas mientras mantiene la longitud de la cadena. Elimina los signos diacríticos (acentos) y utiliza el mapa sugerido por @ marek-stoj para convertir los caracteres Unicode que no son Ascii a sus aproximaciones 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) } }


Si bien esto no responde exactamente a su pregunta, puede convertir su texto Unicode a US-ASCII reemplazando los caracteres que no son ASCII con ''?'' simbolos

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