Set completo di segni di punteggiatura per Python (non solo ASCII)


40

C'è un elenco o una libreria che ha tutte le punteggiatura che potremmo incontrare comunemente?

Normalmente lo uso string.punctuation, ma alcuni caratteri di punteggiatura non sono inclusi in esso, ad esempio:

>>> "'" in string.punctuation
True
>>> "’" in string.punctuation
False


9
@airstrike no affatto.
samuelbrody1249

Risposte:


54

Potresti fare di meglio con questo controllo:

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

Le categorie Unicode P * sono specifiche per la punteggiatura :

connettore (Pc), trattino (Pd), citazione iniziale (Pi), citazione finale (Pf), aperto (Ps), chiuso (Pe), altro (Po)

Per preparare la raccolta esaustiva, che è possibile utilizzare successivamente per controlli rapidi sull'iscrizione, utilizzare una comprensione set:

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

L'espressione di assegnazione qui richiede Python 3.8+, equivalente per le versioni precedenti di Python:

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

Attenzione che alcuni degli altri personaggi in string.punctuationrealtà sono nella categoria Simbolo Unicode . È facile aggiungerli anche se vuoi.


Una definizione ragionevole di "punteggiatura" includerebbe le categorie Unicode "Symbol" Sc (valuta, like $), Sk (modificatore, like ^), Sm (matematica, like +o <) e forse So (altre, like ©).
dan04,

3
@ dan04 Questo è ciò di cui parla l'ultimo paragrafo della risposta. Naturalmente altri possono adattare questo codice per includere / escludere le categorie a seconda del proprio caso d'uso.
mercoledì

16

La risposta inviata da WIM è corretta se si desidera verificare se un personaggio è un carattere di punteggiatura.

Se hai davvero bisogno di un elenco di tutti i caratteri di punteggiatura come suggerisce il titolo della domanda, puoi utilizzare quanto segue:

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

2

La risposta di wim è ottima se puoi cambiare il tuo codice per usare una funzione.

Ma se devi usare l' inoperatore (ad esempio, stai chiamando nel codice della libreria), puoi usare la digitazione duck:

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

1

Sembra un bel lavoro per un'espressione regolare (regexp):

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

Qui, regexp sta abbinando tutto tranne spazi bianchi o caratteri di parole. Il flag re.UNICODEviene utilizzato per abbinare l'intero set di caratteri Unicode.


non funziona con molte lingue:>>> text="Den som dræber - fanget" >>> re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE) 'Den som dr\xc3ber fanget'
samuelbrody1249

1
@ samuelbrody1249 Cosa vuoi dire che non funziona? Funziona nel tuo esempio (la \xc3fuga è una cosa di rappresentazione non correlata allo stripping della punteggiatura).
lenz,

1
@lenz \xc3non è la codifica Unicode corretta di æ; se digiti str(text)puoi confermare che lo è \xc3\xa6. In realtà \xc3non sembra essere un punto di codice completo.
Federico Poloni,

6
Oh, capisco. Sembra che entrambi stiate usando Python 2, dove strc'è una stringa di byte. Dovresti assolutamente passare a Python 3, perché Unicode è un incubo in Py2. Per me, str('æ')mostra come 'æ'e ascii('æ')mostra come '\xe6', che è il punto di codice corretto. b'\xc3\xa6'è la codifica UTF-8 di 'æ', ma di solito non è ciò con cui vuoi lavorare.
lenz,

0

Come hanno indicato altre risposte, il modo per farlo è tramite le proprietà / categorie Unicode. La risposta accettata accede a queste informazioni tramite il unicodedatamodulo di libreria standard , ma a seconda del contesto in cui è necessario, potrebbe essere più veloce o più conveniente accedere a queste stesse informazioni di proprietà usando espressioni regolari.

Tuttavia, il remodulo libreria standard non fornisce supporto Unicode esteso. Per questo, è necessario il regexmodulo , disponibile su 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='’'>

Una buona panoramica di tutti i diversi tipi di proprietà Unicode che puoi cercare usando espressioni regolari è fornita qui . Oltre a queste funzionalità di espressione regolare extra, che sono documentate sulla sua homepage PyPI, regexfornisce deliberatamente la stessa API di re, quindi dovresti usare rela documentazione per capire come usare una di esse.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.