Повний набір розділових знаків для Python (не лише ASCII)


40

Чи є список чи бібліотека, де є всі розділові знаки, які ми зазвичай можемо зустріти?

Зазвичай я використовую string.punctuation, але деякі знаки пунктуації не включаються до нього, наприклад:

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


9
@airstrike немає зовсім.
samuelbrody1249

Відповіді:


54

Ви можете зробити це краще за допомогою цієї перевірки:

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

Категорії Unicode P * призначені спеціально для пунктуації :

з'єднувач (Pc), тире (Pd), початкова цитата (Pi), кінцева цитата (Pf), відкрита (Ps), закрита (Pe), інша (Po)

Щоб підготувати вичерпний збірник, який згодом ви можете використовувати для швидких перевірок членства, використовуйте набір розуміння:

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

Вираз присвоєння тут вимагає Python 3.8+, що еквівалентно старішим версіям Python:

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

Слідкуйте за тим, що деякі інші символи string.punctuationнасправді знаходяться в категорії символу Unicode . Додайте їх також, якщо хочете.


Розумне визначення поняття "пунктуація" включало б категорії "Символ" Unicode "Sc" (валюта, як $), Sk (модифікатор, як ^), Sm (математика, подібне +чи <), а може бути, Так (інше, як ©).
dan04

3
@ dan04 Саме про це згадується останній пункт відповіді. Звичайно, інші можуть адаптувати цей код до включення / виключення категорій залежно від власного випадку використання.
Вім

16

Відповідь, розміщена wim, є правильною, якщо ви хочете перевірити, чи символ є розділовим символом.

Якщо вам справді потрібен список усіх знаків пунктуації, як підказує назва вашої запитання, ви можете скористатися наступним:

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

2

Відповідь wim чудова, якщо ви можете змінити свій код, щоб використовувати функцію.

Але якщо вам доведеться скористатися inоператором (наприклад, ви телефонуєте в код бібліотеки), ви можете використовувати введення качки:

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

Це здається гарною роботою для регулярного виразу (regexp):

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

Тут регулярне вираження відповідає всім, крім пробілів або символів слова. Прапор re.UNICODEвикористовується для узгодження повного набору символів Unicode.


не працює з багатьма мовами:>>> text="Den som dræber - fanget" >>> re.sub(r"[^\w\s]", "", str(text), flags=re.UNICODE) 'Den som dr\xc3ber fanget'
samuelbrody1249

1
@ samuelbrody1249 Що ти означає, що це не працює? Це працює у вашому прикладі ( \xc3втеча - це репрезентативна річ, не пов’язана зі зняттям пунктуації).
lenz

1
@lenz \xc3не є правильним кодуванням Unicode æ; якщо ви введете, str(text)ви можете підтвердити, що це так \xc3\xa6. Насправді \xc3, схоже, це не є повною кодовою точкою.
Федеріко Полоні

6
О Я бачу. Здається, ви обидва використовуєте Python 2, де strє рядок байтів. Ви обов'язково повинні перейти на Python 3, тому що Unicode - це кошмар у Py2. Для мене, str('æ')показує як 'æ', і ascii('æ')показує як '\xe6', що є правильною кодовою точкою. b'\xc3\xa6'- це кодування UTF-8 'æ', але зазвичай це не те, з чим ви хочете працювати.
lenz

0

Як вказували інші відповіді, спосіб зробити це через властивості / категорії Unicode. Прийнята відповідь отримує доступ до цієї інформації через стандартний unicodedataмодуль бібліотеки , але залежно від контексту, де вам це потрібно, може бути швидше або зручніше отримати доступ до цієї самої інформації властивості, використовуючи регулярні вирази.

Однак стандартний reмодуль бібліотеки не забезпечує розширену підтримку Unicode. Для цього вам потрібен regexмодуль , доступний на 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='’'>

Огляд хороший з усіх різних видів властивостей Unicode можна виконати пошук з використанням регулярних виразів забезпечуються тут . Крім цих додаткових функцій регулярного вираження, які задокументовані на його домашній сторінці PyPI, regexнавмисно надається той самий API, що й re, тому ви, як очікується, використовуєте reдокументацію, щоб з'ясувати, як використовувати будь-який з них.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.