Conjunto completo de sinais de pontuação para Python (não apenas ASCII)

40

Existe uma listagem ou biblioteca com todas as pontuações que podemos encontrar normalmente?

Normalmente eu uso string.punctuation, mas alguns caracteres de pontuação não estão incluídos, por exemplo:

>>> "'" in string.punctuation
True
>>> "’" in string.punctuation
False
samuelbrody1249
fonte
Isso responde sua pergunta? Melhor maneira de retirar a pontuação de uma corda
ataque aéreo
9
@airstrike não, de jeito nenhum.
samuelbrody1249

Respostas:

54

Você pode fazer melhor com esta verificação:

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

As categorias Unicode P * são especificamente para pontuação :

conector (Pc), traço (Pd), cotação inicial (Pi), cotação final (Pf), aberto (Ps), fechado (Pe), outro (Po)

Para preparar a coleção completa, que você pode usar posteriormente para verificações rápidas de associação, use uma compreensão definida:

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

A expressão de atribuição aqui requer Python 3.8+, equivalente às versões mais antigas do Python:

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

Cuidado para que alguns dos outros caracteres string.punctuationestejam realmente na categoria Unicode Symbol . É fácil adicioná-los também, se você quiser.

wim
fonte
Uma definição razoável de “pontuação” incluiria as categorias “Símbolo” Unicode Sc (moeda, como $), Sk (modificador, como ^), Sm (matemática, como +ou <) e talvez So (outra, como ©).
dan04 2/04
3
@ dan04 É sobre isso que o último parágrafo da resposta está mencionando. É claro que outras pessoas podem adaptar esse código para incluir / excluir categorias, dependendo do seu próprio caso de uso.
wim 2/04
16

A resposta postada por wim está correta se você deseja verificar se um caractere é um caractere de pontuação.

Se você realmente precisa de uma lista de todos os caracteres de pontuação, como sugere o título da sua pergunta, você pode usar o seguinte:

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

A resposta por wim é ótima se você pode alterar seu código para usar uma função.

Mas se você precisar usar o inoperador (por exemplo, está chamando o código da biblioteca), poderá usar a digitação 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
fonte
1

Parece um trabalho bonito para uma expressão regular (regexp):

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

Aqui, o regexp corresponde a tudo, exceto espaços em branco ou caracteres de palavras. O sinalizador re.UNICODEé usado para corresponder ao conjunto completo de caracteres Unicode.

Nicolas Martinez
fonte
não funciona com muitos idiomas:>>> text="Den som dræber - fanget" >>> re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE) 'Den som dr\xc3ber fanget'
samuelbrody1249
11
@ samuelbrody1249 O que você quer dizer com não funciona? Funciona no seu exemplo (a \xc3fuga é uma coisa de representação não relacionada à remoção de pontuação).
lenz 2/04
11
@lenz \xc3não é a codificação Unicode correta de æ; se você digitar, str(text)pode confirmar que é \xc3\xa6. Na verdade \xc3, não parece ser um ponto de código completo.
Federico Poloni
6
Ah eu vejo. Parece que vocês dois estão usando Python 2, onde strhá uma string de bytes. Você definitivamente deve mudar para o Python 3, porque o Unicode é um pesadelo no Py2. Para mim, str('æ')mostra como 'æ', e ascii('æ')mostra como '\xe6', qual é o ponto de código correto. b'\xc3\xa6'é a codificação UTF-8 de 'æ', mas geralmente não é com isso que você deseja trabalhar.
lenz 2/04
0

Como outras respostas apontaram, a maneira de fazer isso é através de propriedades / categorias Unicode. A resposta aceita acessa essas informações por meio do unicodedatamódulo de biblioteca padrão , mas, dependendo do contexto em que você precisar, pode ser mais rápido ou mais conveniente acessar essas mesmas informações de propriedade usando expressões regulares.

No entanto, o remódulo de biblioteca padrão não fornece suporte estendido a Unicode. Para isso, você precisa do regexmódulo , disponível no 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='’'>

Uma boa visão geral de todos os diferentes tipos de propriedades Unicode que você pode procurar usando expressões regulares é fornecida aqui . Além desses recursos extras de expressão regular, documentados em sua página inicial do PyPI, regexfornece deliberadamente a mesma API que re, portanto, é esperado que você use rea documentação para descobrir como usar qualquer um deles.

dlukes
fonte