web-dev-qa-db-ja.com

Unicode空白のPython定数はありますか?

stringモジュールにはwhitespace属性が含まれています。これは、空白と見なされるすべてのASCII文字で構成される文字列です。Unicodeを含む対応する定数はありますか? no-break space(U + 00A0) ?などのスペースも「 strip()とstrip(string.whitespace)は異なる結果を与える 」という質問からわかります。 "少なくともstripは追加のUnicode空白文字を認識しています。

この質問は Pythonでは、POSIX拡張正規表現[:space:] に一致するすべての文字を一覧表示する方法の重複として識別されましたが、その質問への回答は空白文字を検索して、独自のリストを生成します。これは時間のかかるプロセスです。私の質問は特に定数についてでした。

18
Mark Ransom

Unicode空白のPython定数はありますか?

簡単な答え:いいえ。Python)でこれらの文字(具体的には数値コードポイント)を個人的に調べましたコードベースであり、そのような定数はありません。

以下のセクションでは、それが不要な理由と、この情報を定数として使用せずに実装する方法について説明します。しかし、そのような定数を持つことも本当に悪い考えです。

ユニコードコンソーシアムが意味的に空白である別の文字/コードポイントを追加した場合、Pythonのメンテナーは、意味的に正しくないコードをサポートし続けるか、定数を変更して、場合によっては事前に壊すかを選択できません。定数が変化しないことについて(不可避的に)仮定する可能性のある既存のコード。

これらの文字コードポイントをどのように追加できますか? Unicodeには1,111,998文字の可能な文字があります。ただし、 バージョン8 の時点では、120,672のみが占有されています。 Unicodeの新しいバージョンごとに、文字が追加される場合があります。これらの新しい文字の1つは、空白の形式である可能性があります。

情報は動的に生成されたC関数に格納されます

Unicodeの空白を決定するコードは、動的に生成される次の code です。

# Generate code for _PyUnicode_IsWhitespace()
print("/* Returns 1 for Unicode characters having the bidirectional", file=fp)
print(" * type 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise.", file=fp)
print(" */", file=fp)
print('int _PyUnicode_IsWhitespace(const Py_UCS4 ch)', file=fp)
print('{', file=fp)
print('    switch (ch) {', file=fp)
for codepoint in sorted(spaces):
    print('    case 0x%04X:' % (codepoint,), file=fp)
print('        return 1;', file=fp)
print('    }', file=fp)
print('    return 0;', file=fp)
print('}', file=fp)
print(file=fp)

これは定数コードブロックであるswitchステートメントですが、この情報は、文字列モジュールのように「定数」モジュールとしては利用できません。代わりに、Cからコンパイルされた関数に埋め込まれており、Pythonから直接アクセスすることはできません。

これは、Unicodeにコードポイントが追加されると、下位互換性の理由で定数を変更できなくなるためと考えられます。

生成されたコード

現在生成されているコードは次のとおりです 先端

int _PyUnicode_IsWhitespace(const Py_UCS4 ch)
{
    switch (ch) {
    case 0x0009:
    case 0x000A:
    case 0x000B:
    case 0x000C:
    case 0x000D:
    case 0x001C:
    case 0x001D:
    case 0x001E:
    case 0x001F:
    case 0x0020:
    case 0x0085:
    case 0x00A0:
    case 0x1680:
    case 0x2000:
    case 0x2001:
    case 0x2002:
    case 0x2003:
    case 0x2004:
    case 0x2005:
    case 0x2006:
    case 0x2007:
    case 0x2008:
    case 0x2009:
    case 0x200A:
    case 0x2028:
    case 0x2029:
    case 0x202F:
    case 0x205F:
    case 0x3000:
        return 1;
    }
    return 0;
}

あなた自身の定数を作る:

次のコード(私の答えから ここ )は、Python 3で、すべての空白の定数を生成します:

import re
import sys

s = ''.join(chr(c) for c in range(sys.maxunicode+1))
ws = ''.join(re.findall(r'\s', s))

最適化として、これを新しいプロセスごとに自動生成するのではなく、コードベースに格納することもできますが、変更されないと想定することには注意が必要です。

>>> ws
'\t\n\x0b\x0c\r\x1c\x1d\x1e\x1f \x85\xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000'

(リンクされた質問に対する他の回答は、Python 2)でそれを取得する方法を示しています。)

ある時点で、256文字のエンコーディングだけが必要だと思っていた人もいることを覚えておいてください。

>>> import string
>>> string.whitespace
' \t\n\r\x0b\x0c'

コードベースで定数を維持することを主張している場合は、Pythonのバージョンの定数を生成し、それをリテラルとして格納するだけです。

unicode_whitespace = u'\t\n\x0b\x0c\r\x1c\x1d\x1e\x1f \x85\xa0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000'

uプレフィックスにより、Python 2(2.7は上記の文字列全体も空白として認識されます)およびPython 3文字列リテラルはデフォルトでUnicodeであるため、無視されます。

17
Aaron Hall