完整的Python标点符号集(不仅仅是ASCII)


Answers:


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类别Symbol中。如果需要,也可以轻松添加它们。


合理的“标点符号”定义应包括Unicode“符号”类别Sc(货币,如$),Sk(修饰符,如^),Sm(数学,如+<),以及So(其他,如©)。
dan04

3
@ dan04这就是答案的最后一段。当然,其他人可以根据自己的用例来修改此代码以包括/排除类别。
WIM

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似乎并不是一个完整的代码点。
Federico Poloni

6
哦,我明白了。似乎你们俩都在使用Python 2,其中str是一个字节字符串。您绝对应该切换到Python 3,因为Unicode是Py2的噩梦。对我来说,str('æ')显示为'æ',并且ascii('æ')显示为'\xe6',这是正确的代码点。b'\xc3\xa6'是的UTF-8编码'æ',但这通常不是您想要使用的。
lenz

0

正如其他答案所指出的那样,执行此操作的方法是通过Unicode属性/类别。可接受的答案通过标准库unicodedata模块访问此信息,但是根据需要的上下文,使用正则表达式访问此相同的属性信息可能更快或更方便。

但是,标准库re模块不提供扩展的Unicode支持。为此,您需要在PyPI()上可用的regex模块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的文档来弄清楚如何使用它们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.