Conjunto completo de signos de puntuación para Python (no solo ASCII)

40

¿Hay una lista o biblioteca que tenga todos los signos de puntuación que comúnmente podríamos encontrar?

Normalmente lo uso string.punctuation, pero algunos caracteres de puntuación no están incluidos, por ejemplo:

>>> "'" in string.punctuation
True
>>> "’" in string.punctuation
False
samuelbrody1249
fuente
¿Responde esto a tu pregunta? La mejor manera de eliminar la puntuación de una cadena
ataque aéreo el
99
@airstrike no, no del todo.
samuelbrody1249

Respuestas:

54

Podrías hacerlo mejor con esta verificación:

>>> import unicodedata
>>> unicodedata.category("'").startswith("P")
True
>>> unicodedata.category("’").startswith("P")
True

Las categorías Unicode P * son específicamente para puntuación :

conector (Pc), guión (Pd), comilla inicial (Pi), comilla final (Pf), abrir (Ps), cerrar (Pe), otro (Po)

Para preparar la colección exhaustiva, que luego puede usar para verificaciones de membresía rápidas, use una comprensión establecida:

>>> import sys
>>> from unicodedata import category
>>> codepoints = range(sys.maxunicode + 1)
>>> punctuation = {c for i in codepoints if category(c := chr(i)).startswith("P")}
>>> "'" in punctuation
True
>>> "’" in punctuation
True

La expresión de asignación aquí requiere Python 3.8+, equivalente para versiones anteriores de Python:

chrs = (chr(i) for i in range(sys.maxunicode + 1))
punctuation = set(c for c in chrs if category(c).startswith("P"))

Tenga en cuenta que algunos de los otros caracteres en string.punctuationrealidad están en la categoría Unicode Símbolo . Es fácil agregarlos también si lo desea.

wim
fuente
Una definición razonable de "puntuación" incluiría las categorías Unicode "Símbolo" Sc (moneda, me gusta $), Sk (modificador, me gusta ^), Sm (matemáticas, me gusta +o <), y tal vez So (otra, me gusta ©).
dan04
3
@ dan04 De eso se trata el último párrafo de la respuesta. Por supuesto, otros pueden adaptar este código para incluir / excluir categorías dependiendo de su propio caso de uso.
wim
16

La respuesta publicada por wim es correcta si desea verificar si un carácter es un signo de puntuación.

Si realmente necesita una lista de todos los caracteres de puntuación como sugiere el título de su pregunta, puede usar lo siguiente:

import sys
from unicodedata import category
punctuation_chars =  [chr(i) for i in range(sys.maxunicode) 
                             if category(chr(i)).startswith("P")]
Selcuk
fuente
2

La respuesta de wim es excelente si puede cambiar su código para usar una función.

Pero si tiene que usar el inoperador (por ejemplo, está llamando al código de la biblioteca), puede usar la escritura de pato:

import unicodedata
class DuckType:
    def __contains__(self,s):
        return unicodedata.category(s).startswith("P")
punct=DuckType()
#print("'" in punct,'"' in punct,"a" in punct)
xkcdjerry
fuente
1

Parece un buen trabajo para una expresión regular (regexp):

    import re
    text = re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE)

Aquí, la expresión regular combina todo excepto espacios en blanco o caracteres de palabras. La bandera re.UNICODEse utiliza para hacer coincidir el conjunto completo de caracteres Unicode.

Nicolas Martinez
fuente
no funciona con muchos idiomas:>>> text="Den som dræber - fanget" >>> re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE) 'Den som dr\xc3ber fanget'
samuelbrody1249
1
@ samuelbrody1249 ¿Qué quieres decir con que no funciona? Funciona en su ejemplo (el \xc3escape es una cosa de representación no relacionada con la eliminación de la puntuación).
Len
1
@lenz \xc3no es la codificación Unicode correcta de æ; si escribe str(text)puede confirmar que es así \xc3\xa6. En realidad \xc3no parece ser un punto de código completo.
Federico Poloni
66
Oh ya veo. Parece que ambos están usando Python 2, donde strhay una cadena de bytes. Definitivamente deberías cambiar a Python 3, porque Unicode es una pesadilla en Py2. Para mí, str('æ')muestra como 'æ'y ascii('æ')muestra como '\xe6', que es el punto de código correcto. b'\xc3\xa6'es la codificación UTF-8 de 'æ', pero esto no suele ser con lo que desea trabajar.
Len
0

Como han señalado otras respuestas, la forma de hacerlo es a través de las propiedades / categorías de Unicode. La respuesta aceptada accede a esta información a través del unicodedatamódulo de biblioteca estándar , pero dependiendo del contexto donde lo necesite, podría ser más rápido o más conveniente acceder a esta misma información de propiedad utilizando expresiones regulares.

Sin embargo, el remódulo de biblioteca estándar no proporciona soporte extendido Unicode. Para eso, necesita el regexmódulo , disponible en PyPI ( pip install regex):

>>> import regex as re
>>> re.match("\p{Punctuation}", "'")
<regex.Match object; span=(0, 1), match="'">
>>> re.match("\p{Punctuation}", "’")
<regex.Match object; span=(0, 1), match='’'>

Aquí se proporciona una buena descripción general de todos los diferentes tipos de propiedades Unicode que puede buscar utilizando expresiones regulares . Además de estas características adicionales de expresión regular, que están documentadas en su página de inicio de PyPI, regexproporciona deliberadamente la misma API que re, por lo que se espera que use rela documentación para descubrir cómo usarlas.

dlukes
fuente