Полный набор знаков препинания для Python (не только ASCII) - PullRequest
40 голосов
/ 02 апреля 2020

Есть ли листинг или библиотека, в которой есть все знаки препинания, с которыми мы обычно сталкиваемся?

Обычно я использую string.punctuation, но некоторые знаки препинания не включены в него, например:

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

Ответы [ 5 ]

54 голосов
/ 02 апреля 2020

Вы могли бы сделать лучше с этой проверкой:

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

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

разъем (P c), da sh (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 Symbol . Их легко добавить, если хотите.

16 голосов
/ 02 апреля 2020

Ответ, отправленный wim , является правильным, если вы хотите проверить, является ли символ знаком пунктуации.

Если вам действительно нужен список всех знаков пунктуации, как подсказывает заголовок вашего вопроса , вы можете использовать следующее:

import sys
from unicodedata import category
punctuation_chars =  [chr(i) for i in range(sys.maxunicode) 
                             if category(chr(i)).startswith("P")]
2 голосов
/ 02 апреля 2020

Ответ от 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 голос
/ 02 апреля 2020

Это выглядит как хорошая работа для регулярного выражения (регулярное выражение):

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

Здесь регулярное выражение соответствует всему, кроме пробелов или символов слова. Флаг re.UNICODE используется для сопоставления с полным набором символов Юникода.

0 голосов
/ 07 апреля 2020

Как уже отмечалось в других ответах, способ сделать это - через свойства / категории Unicode. Принятый ответ обращается к этой информации через стандартный модуль unicodedata библиотеки, но в зависимости от контекста, где это необходимо, может быть быстрее или удобнее получить доступ к этой же информации о свойствах с помощью регулярных выражений.

Однако стандартная библиотека re module не обеспечивает расширенную поддержку 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, чтобы выяснить, как использовать любой из их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...