Quiero verificar si una cadena está en ASCII o no.
Soy consciente ord()
, sin embargo, cuando lo intento ord('é')
, lo he hecho TypeError: ord() expected a character, but string of length 2 found
. Comprendí que es causado por la forma en que construí Python (como se explica en ord()
la documentación ).
¿Hay otra forma de verificar?
Respuestas:
fuente
ord(c) < 128
es infinitamente más legible e intuitivo quec <= "\x7F"
Creo que no estás haciendo la pregunta correcta.
Una cadena en python no tiene ninguna propiedad correspondiente a 'ascii', utf-8 o cualquier otra codificación. La fuente de su cadena (ya sea que la lea de un archivo, la entrada de un teclado, etc.) puede haber codificado una cadena unicode en ascii para producir su cadena, pero ahí es donde debe buscar una respuesta.
Quizás la pregunta que puede hacer es: "¿Es esta cadena el resultado de codificar una cadena unicode en ascii?" - Esto puede responder intentando:
fuente
str
en Python 2,bytes
en Python 3).str
en cualquier codificación ISO necesitaría codificarse primero a Unicode. La respuesta debería entrar en esto.s.decode('ascii') if isinstance(s, bytes) else s.encode('ascii')
en Python 3. La entrada de OP es una cadena de bytes'é'
(sintaxis de Python 2, Python 3 no se había lanzado en ese momento) y, por.decode()
lo tanto, es correcta.str
en Python 2 es una cadena de bytes. Es correcto usarlo.decode('ascii')
para averiguar si todos los bytes están en el rango ASCII.Python 3 vías:
Para verificar, pase la cadena de prueba:
fuente
isascii
ahora es una función que pase una cadena:isascii('somestring')
==True
yisascii('àéç')
==False
try: s.encode('ascii'); return True
except UnicodeEncodeError: return False
(como arriba, pero codificación, ya que las cadenas son Unicode en Python 3). Esta respuesta también genera un error en Python 3 cuando tiene sustitutos (por ejemplo,isascii('\uD800')
genera un error en lugar de regresarFalse
)Nuevo en Python 3.7 ( bpo32677 )
No más verificaciones ascii aburridas / ineficientes en las cadenas, nuevo método /
str
/ incorporado : verificará si las cadenas son ascii.bytes
bytearray
.isascii()
fuente
"\x03".isascii()
También es cierto. La documentación dice que esto solo verifica que todos los caracteres estén por debajo del punto de código 128 (0-127). Si también quiere evitar los caracteres de control, se necesita:text.isascii() and text.isprintable()
. Solo usarloisprintable
por sí solo tampoco es suficiente, ya que considerará que un carácter como ¿se puede imprimir (correctamente), pero no está dentro de la sección de impresión ASCII, por lo que debe verificar ambos si desea ambos. Otro problema: los espacios se consideran imprimibles, las pestañas y las nuevas líneas no.Me encontré con algo como esto recientemente, para referencia futura
que podrías usar con:
fuente
{'confidence': 0.99, 'encoding': 'EUC-JP'}
(que en este caso estaba completamente equivocado)Vincent Marchetti tiene la idea correcta, pero
str.decode
ha quedado en desuso en Python 3. En Python 3 puede hacer la misma prueba constr.encode
:Tenga en cuenta que la excepción que desea capturar también ha cambiado de
UnicodeDecodeError
aUnicodeEncodeError
.fuente
bytes
escriba Python 3 que no tiene.encode()
método)..decode()
en @Vincent Marchetti la respuesta es correcta .'é'
era una cadena de bytes en ese momento.Tu pregunta es incorrecta; el error que ves no es el resultado de cómo construiste python, sino de una confusión entre cadenas de bytes y cadenas unicode.
Las cadenas de bytes (por ejemplo, "foo", o 'bar', en sintaxis de python) son secuencias de octetos; números del 0-255. Las cadenas Unicode (por ejemplo, u "foo" o u'bar ') son secuencias de puntos de código unicode; números del 0-1112064. Pero parece estar interesado en el carácter é, que (en su terminal) es una secuencia de varios bytes que representa un solo carácter.
En lugar de
ord(u'é')
, intente esto:Eso te dice qué secuencia de puntos de código representa "é". Puede darle [233], o puede darle [101, 770].
En lugar de
chr()
revertir esto, hayunichr()
:Este personaje puede representarse en realidad como "puntos de código" unicode simples o múltiples, que a su vez representan grafemas o caracteres. Es "e con un acento agudo (es decir, punto de código 233)" o "e" (punto de código 101), seguido de "un acento agudo en el carácter anterior" (punto de código 770). Por lo que este mismo carácter exacto puede ser presentada como la estructura de datos de Python
u'e\u0301'
ou'\u00e9'
.La mayoría de las veces no debería preocuparse por esto, pero puede convertirse en un problema si está iterando sobre una cadena Unicode, ya que la iteración funciona por punto de código, no por caracteres descomponibles. En otras palabras,
len(u'e\u0301') == 2
ylen(u'\u00e9') == 1
. Si esto es importante para usted, puede convertir entre formas compuestas y descompuestas utilizandounicodedata.normalize
.El Glosario Unicode puede ser una guía útil para comprender algunos de estos problemas, al señalar cómo cada término específico se refiere a una parte diferente de la representación del texto, que es mucho más complicado de lo que muchos programadores se dan cuenta.
fuente
¿Qué tal hacer esto?
fuente
Encontré esta pregunta al intentar determinar cómo usar / codificar / decodificar una cadena de cuya codificación no estaba seguro (y cómo escapar / convertir caracteres especiales en esa cadena).
Mi primer paso debería haber sido verificar el tipo de la cadena: no me di cuenta de que podía obtener buenos datos sobre su formato de tipo (s). Esta respuesta fue muy útil y llegó a la raíz real de mis problemas.
Si te estás volviendo grosero y persistente
particularmente cuando está CODIFICANDO, asegúrese de que no está tratando de unicode () una cadena que ya ES unicode- por alguna razón terrible, obtiene errores de códec ASCII. (Consulte también la receta de Python Kitchen y los tutoriales de documentación de Python para comprender mejor lo terrible que puede ser).
Finalmente, determiné que lo que quería hacer era esto:
También fue útil para depurar la configuración de la codificación predeterminada en mi archivo a utf-8 (ponga esto al comienzo de su archivo python):
Eso le permite probar caracteres especiales ('àéç') sin tener que usar sus escapes unicode (u '\ xe0 \ xe9 \ xe7').
fuente
Para mejorar la solución de Alexander desde Python 2.6 (y en Python 3.x) puede usar el módulo auxiliar curses.ascii y usar la función curses.ascii.isascii () u otra: https://docs.python.org/2.6/ library / curses.ascii.html
fuente
curses.ascii
Puede usar la biblioteca de expresiones regulares que acepta la definición estándar [[: ASCII:]] de Posix.
fuente
Una picadura (
str
tipo) en Python es una serie de bytes. No hay forma de saber con solo mirar la cadena si esta serie de bytes representa una cadena ascii, una cadena en un juego de caracteres de 8 bits como ISO-8859-1 o una cadena codificada con UTF-8 o UTF-16 o lo que sea .Sin embargo, si conoce la codificación utilizada, puede
decode
convertir la cadena en una cadena unicode y luego usar una expresión regular (o un bucle) para verificar si contiene caracteres fuera del rango que le preocupa.fuente
Me gusta la respuesta de @ RogerDahl, pero es más eficiente hacer un cortocircuito al negar la clase de caracteres y usar la búsqueda en lugar de
find_all
omatch
.Me imagino que una expresión regular está bien optimizada para esto.
fuente
Para incluir una cadena vacía como ASCII, cambie el
+
a*
.fuente
Para evitar que su código se bloquee, es posible que desee utilizar un
try-except
para atraparTypeErrors
Por ejemplo
fuente
try
envoltorio es completamente inútil. Si"¶"
es una cadena Unicode, entoncesord("¶")
funcionará, y si no lo es (Python 2), lafor c in s
descompondrá en bytes paraord
que continúe funcionando.Utilizo lo siguiente para determinar si la cadena es ascii o unicode:
Luego, use un bloque condicional para definir la función:
fuente
is_ascii(u'i am ascii')
. Aunque las letras y los espacios son definitivamente ASCII, esto todavía regresaFalse
porque forzamos la cadena a serunicode
.