14

IPython での次の交換を検討してください。

In [1]: s = u'華袞與緼同歸'

In [2]: len(s)
Out[2]: 8

正しい出力は であるはずですが7、これらの 7 つの漢字の 5 番目は Unicode コードポイントが高いため、単なる 1 つのコードポイントではなく、「サロゲート ペア」によって UTF-8 で表され、結果として Python 1文字ではなく2文字だと思います。

unicodedataサロゲート ペアを単一のコードポイント () として正しく返すを使用しても、間違った長さ\U00026177に渡された場合len()でも返されます。

In [3]: import unicodedata

In [4]: unicodedata.normalize('NFC', s)
Out[4]: u'\u83ef\u889e\u8207\u7dfc\U00026177\u540c\u6b78'


In [5]: len(unicodedata.normalize('NFC', s))
Out[5]: 8

Python を UTF-32 用に再コンパイルするような抜本的な手順を踏まずに、このような状況で正しい長さを取得する簡単な方法はありますか?

私は IPython 0.13、Python 2.7.2、Mac OS 10.8.2 を使用しています。

4

3 に答える 3

8

これは3.3で修正されたと思います。見る:

http://docs.python.org/py3k/whatsnew/3.3.html
http://www.python.org/dev/peps/pep-0393/ (検索wstr_length)

于 2012-10-20T16:10:51.823 に答える
7

Python 2 でこれを行う関数を作成します。

SURROGATE_PAIR = re.compile(u'[\ud800-\udbff][\udc00-\udfff]', re.UNICODE)
def unicodeLen(s):
  return len(SURROGATE_PAIR.sub('.', s))

サロゲート ペアを 1 文字に置き換えることで、関数を「修正」しlenます。通常の文字列では、これは非常に効率的です。パターンが一致しないため、元の文字列が変更されずに返されます。サロゲート ペア エンコーディングが使用されないため、ワイド (32 ビット) Python ビルドでも動作するはずです。

于 2015-04-14T17:42:18.887 に答える