Kompletny zestaw znaków interpunkcyjnych dla Pythona (nie tylko ASCII)

40

Czy istnieje lista lub biblioteka zawierająca wszystkie znaki interpunkcyjne, z którymi często się spotykamy?

Zwykle używam string.punctuation, ale niektóre znaki interpunkcyjne nie są w nim zawarte, na przykład:

>>> "'" in string.punctuation
True
>>> "’" in string.punctuation
False
samuelbrody1249
źródło
Czy to odpowiada na twoje pytanie? Najlepszy sposób na usunięcie interpunkcji ze struny
nalot
9
@airstrike nie wcale.
samuelbrody1249

Odpowiedzi:

54

Przydałaby Ci się ta kontrola:

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

Kategorie Unicode P * dotyczą specjalnie interpunkcji :

złącze (Pc), myślnik (Pd), wstępny cytat (Pi), końcowy cytat (Pf), otwórz (Ps), zamknij (Pe), inny (Po)

Aby przygotować wyczerpującą kolekcję, którą możesz następnie wykorzystać do szybkiej kontroli członkostwa, użyj zestawu:

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

Wyrażenie przypisania tutaj wymaga Python 3.8+, odpowiednik dla starszych wersji Python:

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

Uważaj, że niektóre inne znaki w string.punctuationrzeczywistości znajdują się w symbolu kategorii Unicode . Możesz je łatwo dodać, jeśli chcesz.

wim
źródło
Rozsądna definicja „interpunkcji” obejmuje kategorie Unicode „Symbol” Sc (waluta, jak $), Sk (modyfikator, jak ^), Sm (matematyka, jak +lub <), a może So (inne, jak ©).
dan04
3
@ dan04 O tym właśnie wspomina ostatni akapit odpowiedzi. Oczywiście inni mogą dostosować ten kod w celu uwzględnienia / wykluczenia kategorii w zależności od własnego przypadku użycia.
wim
16

Odpowiedź wysłana przez wim jest poprawna, jeśli chcesz sprawdzić, czy znak jest znakiem interpunkcyjnym.

Jeśli naprawdę potrzebujesz listy wszystkich znaków interpunkcyjnych, jak sugeruje tytuł pytania, możesz użyć następujących opcji:

import sys
from unicodedata import category
punctuation_chars =  [chr(i) for i in range(sys.maxunicode) 
                             if category(chr(i)).startswith("P")]
Selcuk
źródło
2

Odpowiedź wim jest świetna, jeśli możesz zmienić kod, aby użyć funkcji.

Ale jeśli musisz użyć inoperatora (na przykład dzwonisz do kodu biblioteki), możesz użyć wpisywania kaczki:

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
źródło
1

To wygląda na niezłą robotę dla wyrażenia regularnego (regexp):

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

Wyrażenie regularne dopasowuje tutaj wszystko oprócz białych znaków i znaków słownych. Flaga re.UNICODEsłuży do dopasowania pełnego zestawu znaków Unicode.

Nicolas Martinez
źródło
nie działa w wielu językach:>>> text="Den som dræber - fanget" >>> re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE) 'Den som dr\xc3ber fanget'
samuelbrody1249
1
@ samuelbrody1249 Co masz na myśli mówiąc, że to nie działa? Działa to w twoim przykładzie ( \xc3ucieczka jest rzeczą związaną z usuwaniem interpunkcji).
lenz
1
@lenz \xc3nie jest poprawnym kodowaniem Unicode æ; jeśli wpiszesz str(text), możesz potwierdzić, że tak jest \xc3\xa6. W rzeczywistości \xc3nie wydaje się być kompletnym punktem kodowym.
Federico Poloni
6
Rozumiem. Wygląda na to, że oboje korzystacie z Python 2, gdzie strjest ciąg bajtów. Zdecydowanie powinieneś przejść na Python 3, ponieważ Unicode to koszmar w Py2. Dla mnie str('æ')pokazuje jako 'æ'i ascii('æ')pokazuje jako '\xe6', który jest poprawnym punktem kodowym. b'\xc3\xa6'jest kodowaniem UTF-8 'æ', ale zwykle nie jest to z czym chcesz pracować.
lenz
0

Jak wskazały inne odpowiedzi, sposobem na to jest skorzystanie z właściwości / kategorii Unicode. Zaakceptowana odpowiedź uzyskuje dostęp do tych informacji za pośrednictwem standardowego unicodedatamodułu biblioteki , ale w zależności od kontekstu, w którym jest to potrzebne, może być szybszy lub wygodniejszy dostęp do tej samej informacji o właściwości za pomocą wyrażeń regularnych.

Jednak standardowy remoduł biblioteczny nie zapewnia rozszerzonej obsługi Unicode. Do tego potrzebny jest regexmoduł dostępny w 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='’'>

Warunkiem jest dobry przegląd wszystkich różnych rodzajów właściwości Unicode można wyszukiwać za pomocą wyrażeń regularnych tutaj . Oprócz tych dodatkowych funkcji wyrażeń regularnych, które są udokumentowane na stronie głównej PyPI, regexcelowo udostępnia ten sam interfejs API co re, więc należy się spodziewać po redokumentacji, aby dowiedzieć się, jak korzystać z którejkolwiek z nich.

dlukes
źródło