2

可能重复:
在 Python 中,如何列出与 POSIX 扩展正则表达式 `[:space:]` 匹配的所有字符?

如何在 Python 中获取 UTF-8 中所有空格的列表?包括不间断空间等。我使用的是 python 2.7。

4

3 回答 3

9

unicodedata.category将告诉您任何给定字符的类别代码;你想要的字符有代码Zs。除了遍历所有字符之外,似乎没有任何方法可以提取类别中的字符列表:

>>> for c in xrange(sys.maxunicode+1):
...     u = unichr(c)
...     if unicodedata.category(u) == 'Zs':
...         sys.stdout.write("U+{:04X} {}\n".format(c, unicodedata.name(u)))
... 
U+0020 SPACE
U+00A0 NO-BREAK SPACE
U+1680 OGHAM SPACE MARK
U+180E MONGOLIAN VOWEL SEPARATOR
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE

(注意:如果您使用 Python 3.4 或更高版本进行此测试,蒙古元音分隔符将不会出现在列表中。Python 2.7 附带来自 Unicode 5.2 的数据;此字符在 Unicode 6.3 中被重新分类为通用类别 Cf(“格式控制”) , 这是 Python 3.4 用于其数据的版本。请参阅https://codeblog.jonskeet.uk/2014/12/01/when-is-an-identifier-not-an-identifier-attack-of-the- mongolian-vowel-separator/https://www.unicode.org/L2/L2013/13004-vowel-sep-change.pdf以获得比您可能需要的更多详细信息。)

您可能还想包括类别ZlZp,这增加了

U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR

而且您几乎可以肯定想要包含所有通常被认为是空白的 ASCII 控制字符——出于历史原因(我想),这些都在 category 中Cc

U+0009 CHARACTER TABULATION  ('\t')
U+000A LINE FEED (LF)        ('\n')
U+000B LINE TABULATION       ('\v')
U+000C FORM FEED (FF)        ('\r')
U+000D CARRIAGE RETURN (CR)  ('\f')

其他 60 多个Cc字符不应视为空格,即使它们的正式名称听起来像是空格。例如,U+0085 NEXT LINE几乎从来没有在野外遇到过它的官方含义;它更有可能是从 Windows-1252 到 UTF-8 的错误转换的结果U+2026 HORIZONTAL ELLIPSIS

一个密切相关的问题是“ \sPython 正则表达式中的匹配项是什么?” 再次回答这个问题的最佳方法是遍历所有字符:

>>> s = re.compile(ru"^\s$", re.UNICODE)
>>> for c in range(sys.maxunicode+1):
...   u = unichr(c)
...   if s.match(u):
...      sys.stdout.write("U+{:04X} {}\n".format(
...        c, unicodedata.name(u, "<name missing>")))
U+0009 <name missing>
U+000A <name missing>
U+000B <name missing>
U+000C <name missing>
U+000D <name missing>
U+001C <name missing>
U+001D <name missing>
U+001E <name missing>
U+001F <name missing>
U+0020 SPACE
U+0085 <name missing>
U+00A0 NO-BREAK SPACE
U+1680 OGHAM SPACE MARK
U+180E MONGOLIAN VOWEL SEPARATOR
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE

(我不知道为什么unicodedata.name不知道控制字符的名称。同样,如果您使用 Python 3.4 或更高版本进行此测试,蒙古元音分隔符将不会出现在列表中。)

这是所有的Z*字符,所有Cc普遍认为是空白的字符,还有五个额外的普遍认为是空白的字符,U+001C、U+001D、U+001E、U+001F和U +0085。包含最后一组是一个错误,但在很大程度上是无害的,因为这些字符用于任何事情也是一个错误。

于 2013-01-09T19:52:34.047 回答
3

Zs类别可能还不够:

#!/usr/bin/env python
import sys
import unicodedata

import regex # $ pip install regex

for i in xrange(sys.maxunicode + 1):
    u = unichr(i)
    if regex.match(u"[[:space:]]", u):
        try:
            name = unicodedata.name(u)
        except ValueError:
            name = ""
        print("{:9s} {} {}".format(repr(u), unicodedata.category(u), name))

输出

u'\t'     Cc 
u'\n'     Cc 
u'\x0b'   Cc 
u'\x0c'   Cc 
u'\r'     Cc 
u' '      Zs SPACE
u'\x85'   Cc 
u'\xa0'   Zs NO-BREAK SPACE
u'\u1680' Zs OGHAM SPACE MARK
u'\u180e' Zs MONGOLIAN VOWEL SEPARATOR
u'\u2000' Zs EN QUAD
u'\u2001' Zs EM QUAD
u'\u2002' Zs EN SPACE
u'\u2003' Zs EM SPACE
u'\u2004' Zs THREE-PER-EM SPACE
u'\u2005' Zs FOUR-PER-EM SPACE
u'\u2006' Zs SIX-PER-EM SPACE
u'\u2007' Zs FIGURE SPACE
u'\u2008' Zs PUNCTUATION SPACE
u'\u2009' Zs THIN SPACE
u'\u200a' Zs HAIR SPACE
u'\u2028' Zl LINE SEPARATOR
u'\u2029' Zp PARAGRAPH SEPARATOR
u'\u202f' Zs NARROW NO-BREAK SPACE
u'\u205f' Zs MEDIUM MATHEMATICAL SPACE
u'\u3000' Zs IDEOGRAPHIC SPACE
于 2013-01-09T20:39:25.357 回答
0

unicode 数据库中的官方空格字符列表是通过“Zs”类别定义的:

http://www.fileformat.info/info/unicode/category/Zs/list.htm

我不确定 Python 的 unicodedata 模块中是否有功能。我怀疑:您可以查看所有字符并根据“Zs”检查它们的类别。

于 2013-01-09T19:52:02.853 回答