Tengo un archivo de texto del que estoy leyendo líneas y procesando cada línea una por una.

Me encontré con esta línea:

(T)he film is never sure to make a clear point – even if it seeks to rely on an ambiguous presentation.

Entre point y even tengo tres caracteres , - y .

Intenté imprimir los caracteres como números enteros.

En Java:

String input = "(T)he film is never sure to make a clear point – even if it seeks to rely on an ambiguous presentation.";
int[] ords = new int[input.length()];
for (int i = 0; i < ords.length; i++)
    ords[i] = (int) input.charAt(i);

Que da:

[40, 84, 41, 104, 101, 32, 102, 105, 108, 109, 32, 105, 115, 32, 110, 101, 118, 101, 114, 32, 115, 117, 114, 101, 32, 116, 111, 32, 109, 97, 107, 101, 32, 97, 32, 99, 108, 101, 97, 114, 32, 112, 111, 105, 110, 116, 32, 8211, 32, 101, 118, 101, 110, 32, 105, 102, 32, 105, 116, 32, 115, 101, 101, 107, 115, 32, 116, 111, 32, 114, 101, 108, 121, 32, 111, 110, 32, 97, 110, 32, 97, 109, 98, 105, 103, 117, 111, 117, 115, 32, 112, 114, 101, 115, 101, 110, 116, 97, 116, 105, 111, 110, 46]

En Python:

def get_ords(string):
    return map(lambda x: ord(x), string)

Que da:

[40, 84, 41, 104, 101, 32, 102, 105, 108, 109, 32, 105, 115, 32, 110, 101, 118, 101, 114, 32, 115, 117, 114, 101, 32, 116, 111, 32, 109, 97, 107, 101, 32, 97, 32, 99, 108, 101, 97, 114, 32, 112, 111, 105, 110, 116, 32, 226, 128, 147, 32, 101, 118, 101, 110, 32, 105, 102, 32, 105, 116, 32, 115, 101, 101, 107, 115, 32, 116, 111, 32, 114, 101, 108, 121, 32, 111, 110, 32, 97, 110, 32, 97, 109, 98, 105, 103, 117, 111, 117, 115, 32, 112, 114, 101, 115, 101, 110, 116, 97, 116, 105, 111, 110, 46]

En el resultado de Java, los tres caracteres , - y están representados por 8211 y en Python se representa como 226, 128, 147 es decir '\xe2', '\x80', '\x93' . Esta discrepancia da como resultado resultados diferentes cuando lo proceso en Java y Python.

También noté que si elimino , - y de la cadena, los resultados son los mismos para ambos.

¿Es posible resolver este problema sin tener que eliminar los caracteres especiales?

1
Animesh Pandey 13 ene. 2017 a las 03:53
1
Quizás esta respuesta pueda ayudarte.
 – 
Pierre C.
13 ene. 2017 a las 04:03

3 respuestas

Probablemente no lo esté usando como una cadena Unicode en Python (prefijo u en Python 2).

Esto se puede ilustrar con el siguiente código (usando la parte relevante de su ejemplo):

# -*- coding: utf-8 -*-

x = u"t – e"
y = "t – e"

def get_ords(s):
    return map(lambda x: ord(x), s)

print "x: %s" % (get_ords(x),)
print "y: %s" % (get_ords(y),)

El resultado es:

x: [116, 32, 8211, 32, 101]
y: [116, 32, 226, 128, 147, 32, 101]

Esta documentación de Python sobre Unicode debería ser de interés: https://docs.python.org/ 2 / howto / unicode.html

Al leer de un archivo, puede usar codecs; de lo contrario , no está leyendo el archivo como Unicode:

import codecs

with codecs.open('test.txt','r','utf-8') as f:
    x = f.read()

with open('test.txt','r') as f:
    y = f.read()

(Esto produce los mismos resultados que los anteriores).

Tenga en cuenta que, en Java, la codificación utilizada para la lectura también puede depender del valor de la propiedad del sistema file.encoding. (Depende de cómo lea el archivo, consulte: https: // docs.oracle.com/javase/tutorial/i18n/text/stream.html)

3
Bruno 13 ene. 2017 a las 04:19
Respuesta muy completa y completa!
 – 
David542
13 ene. 2017 a las 09:35

Me aseguraría de que la cadena tenga la misma codificación en ambos. Por ejemplo, para Python haría algo como lo siguiente para ponerlo en utf8:

def get_ords(string):
    string = string.encode('utf-8')
    return map(lambda x: ord(x), string)
0
David542 13 ene. 2017 a las 03:59

Si bien la respuesta dada por @Bruno es muy buena, pude resolver mi problema usando la siguiente función:

from unidecode import unidecode

def remove_non_ascii(text):
    return unidecode(unicode(text, encoding="utf-8"))

Para cualquier cadena utilicé remove_non_ascii y lo mismo en Java.

0
Animesh Pandey 17 ene. 2017 a las 05:29