Ensemble complet de signes de ponctuation pour Python (pas seulement ASCII)


40

Existe-t-il une liste ou une bibliothèque contenant toutes les ponctuations que nous pourrions rencontrer couramment?

Normalement string.punctuation, j'utilise , mais certains caractères de ponctuation n'y sont pas inclus, par exemple:

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


9
@airstrike non pas du tout.
samuelbrody1249

Réponses:


54

Vous pourriez faire mieux avec cette vérification:

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

Les catégories Unicode P * sont spécifiquement destinées à la ponctuation :

connecteur (Pc), tiret (Pd), devis initial (Pi), devis final (Pf), ouvert (Ps), fermé (Pe), autre (Po)

Pour préparer la collection exhaustive, que vous pouvez ensuite utiliser pour des vérifications d'adhésion rapides, utilisez une compréhension d'ensemble:

>>> 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'expression d'affectation ici nécessite Python 3.8+, équivalent pour les anciennes versions de Python:

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

Sachez que certains des autres caractères de string.punctuationsont en fait dans la catégorie Unicode Symbole . Il est facile de les ajouter également si vous le souhaitez.


Une définition raisonnable de la «ponctuation» inclurait les catégories Unicode «Symbole» Sc (devise, comme $), Sk (modificateur, comme ^), Sm (math, comme +ou <), et peut-être So (autre, comme ©).
dan04

3
@ dan04 C'est de cela que parle le dernier paragraphe de la réponse. Bien sûr, d'autres peuvent adapter ce code pour inclure / exclure des catégories en fonction de leur propre cas d'utilisation.
wim

16

La réponse publiée par wim est correcte si vous voulez vérifier si un caractère est un caractère de ponctuation.

Si vous avez vraiment besoin d'une liste de tous les caractères de ponctuation comme le suggère le titre de votre question, vous pouvez utiliser ce qui suit:

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

2

La réponse de wim est excellente si vous pouvez changer votre code pour utiliser une fonction.

Mais si vous devez utiliser l' inopérateur (par exemple, vous appelez dans le code de bibliothèque), vous pouvez utiliser la frappe de canard:

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

Cela semble être un joli travail pour une expression régulière (regexp):

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

Ici, l'expression rationnelle correspond à tout sauf aux espaces blancs ou aux caractères de mot. Le drapeau re.UNICODEest utilisé pour faire correspondre un ensemble complet de caractères Unicode.


ne fonctionne pas avec de nombreuses langues:>>> text="Den som dræber - fanget" >>> re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE) 'Den som dr\xc3ber fanget'
samuelbrody1249

1
@ samuelbrody1249 Que voulez-vous dire que cela ne fonctionne pas? Cela fonctionne dans votre exemple (l' \xc3évasion est une chose de représentation sans rapport avec le dépouillement de la ponctuation).
lenz

1
@lenz \xc3n'est pas le codage Unicode correct de æ; si vous tapez, str(text)vous pouvez confirmer que c'est le cas \xc3\xa6. En fait, \xc3cela ne semble pas être un point de code complet.
Federico Poloni

6
Oh je vois. Il semble que vous utilisiez tous les deux Python 2, où se strtrouve une chaîne d'octets. Vous devriez certainement passer à Python 3, car Unicode est un cauchemar dans Py2. Pour moi, str('æ')montre comme 'æ', et ascii('æ')montre comme '\xe6', qui est le bon point de code. b'\xc3\xa6'est le codage UTF-8 'æ', mais ce n'est généralement pas ce avec quoi vous voulez travailler.
lenz

0

Comme d'autres réponses l'ont souligné, la façon de le faire est via les propriétés / catégories Unicode. La réponse acceptée accède à ces informations via le unicodedatamodule de bibliothèque standard , mais selon le contexte où vous en avez besoin, il peut être plus rapide ou plus pratique d'accéder à ces mêmes informations de propriété à l'aide d'expressions régulières.

Cependant, le remodule de bibliothèque standard ne fournit pas de prise en charge étendue d'Unicode. Pour cela, vous avez besoin du regexmodule , disponible sur 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='’'>

Un bon aperçu de tous les différents types de propriétés Unicode que vous pouvez rechercher à l'aide d'expressions régulières est fourni ici . Outre ces fonctionnalités d'expression régulière supplémentaires, qui sont documentées sur sa page d'accueil PyPI, regexfournit délibérément la même API que re, vous êtes donc censé utiliser rela documentation de pour comprendre comment utiliser l'une ou l'autre.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.