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) < 128es 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
stren Python 2,bytesen Python 3).stren 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.stren 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
isasciiahora es una función que pase una cadena:isascii('somestring')==Trueyisascii('àéç')==Falsetry: s.encode('ascii'); return Trueexcept 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.bytesbytearray.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 usarloisprintablepor 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.decodeha 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
UnicodeDecodeErroraUnicodeEncodeError.fuente
bytesescriba 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') == 2ylen(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.asciiPuede usar la biblioteca de expresiones regulares que acepta la definición estándar [[: ASCII:]] de Posix.
fuente
Una picadura (
strtipo) 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
decodeconvertir 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_allomatch.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-exceptpara atraparTypeErrorsPor ejemplo
fuente
tryenvoltorio es completamente inútil. Si"¶"es una cadena Unicode, entoncesord("¶")funcionará, y si no lo es (Python 2), lafor c in sdescompondrá en bytes paraordque 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 regresaFalseporque forzamos la cadena a serunicode.