Python unicodedata
since 2011-04-20
http://docs.python.jp/2.7/library/unicodedata.html
Unicode を理解すると何をやってるのかわかってくる。。
Unicode HOWTO http://docs.python.jp/2/howto/unicode.html
<html> <div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414164X/r4wh-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51b7R1hZL-L._SL160_.jpg" alt="プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414164X/r4wh-22/ref=nosim/" name="amazletlink" target="_blank">プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 13.01.13</div></div><div class="amazlet-detail">矢野 啓介 <br />技術評論社 <br />売り上げランキング: 14,076<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/477414164X/r4wh-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div> </html>
- NFC: normalization form + composed
- NFKC: NFC + K (=Compatibility) 全角半角など互換文字の変換を行う
Text Processing in Python by David Mertz – published by Addison Wesley
スペース
「スペース」の category を見てみた:
http://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9
>>> unicodedata.category(u'\u0020') 'Zs' >>> unicodedata.category(u'\u00a0') 'Zs' >>> unicodedata.category(u'\u2002') 'Zs' >>> unicodedata.category(u'\u2003') 'Zs' >>> unicodedata.category(u'\u2004') 'Zs' >>> unicodedata.category(u'\u2005') 'Zs' >>> unicodedata.category(u'\u2009') 'Zs' >>> unicodedata.category(u'\u2006') 'Zs' >>> unicodedata.category(u'\u2007') 'Zs' >>> unicodedata.category(u'\u2008') 'Zs' >>> unicodedata.category(u'\u200a') 'Zs' >>> unicodedata.category(u'\u200b') 'Cf' >>> unicodedata.category(u'\u3000') 'Zs' >>> unicodedata.category(u'\ufeff') 'Cf' >>> unicodedata.category(u'\u0009') 'Cc'
normalize
http://tama-san.com/old/document06.html
全角文字を半角文字に正規化できる:
>>> import unicodedata >>> unicodedata.normalize('NFKC', u'100') u'100' >>> unicodedata.normalize('NFKC', u'.') u'.' >>> unicodedata.normalize('NFKC', u'・') u'\u30fb' >>> unicodedata.normalize('NFKC', u'、') u'\u3001' >>> unicodedata.normalize('NFKC', u'A') u'A' >>> unicodedata.normalize('NFKC', u'~') u'~'
一般に「チルダ」「波ダッシュ」のような文字:
>>> '%04x' % ord(u'~') '007e' >>> unichr(0x301c) u'\u301c' >>> '%04x' % ord(u'~') 'ff5e'
301c は正規化で変換されない:
>>> '%04x' % ord(unicodedata.normalize('NFKC', unichr(0x007e))) '007e' >>> '%04x' % ord(unicodedata.normalize('NFKC', unichr(0x301c))) '301c' >>> '%04x' % ord(unicodedata.normalize('NFKC', unichr(0xff5e))) '007e'
ちなみにコマンドプロンプトで下記を実行すると 003f が出てくるが、文字変換に失敗して '?' になったらしい:
>>> '%04x' % ord(u'〜') '003f'
エンマークは全角¥(0xffe5)を正規化するとバックスラッシュ(0x005c)ではなく Unicode の円記号(0x00a5)に変換される:
>>> '%04x' % ord(u'¥') 'ffe5' >>> '%04x' % ord(u'\\') '005c' >>> unichr(0x00a5) u'\xa5' >>> '%04x' % ord(unicodedata.normalize('NFKC', unichr(0x00a5))) '00a5' >>> '%04x' % ord(unicodedata.normalize('NFKC', unichr(0x005c))) '005c' >>> '%04x' % ord(unicodedata.normalize('NFKC', unichr(0xffe5))) '00a5'
全角バックスラッシュの正規化:
>>> '%04x' % ord(u'\') 'ff3c' >>> '%04x' % ord(unicodedata.normalize('NFKC', u'\')) '005c'
全角オーバーライン(?)を正規化すると「空白」と COMBINING MACRON の2文字になる:
>>> '%04x' % ord(u' ̄') 'ffe3' >>> unicodedata.normalize('NFKC', u' ̄') u' \u0304'
NFKC (composed) でもNFKD (decomposed) でも同じ結果になる:
>>> '%04x' % ord(unicodedata.normalize('NFKC', u' ̄')[0]) '0020' >>> '%04x' % ord(unicodedata.normalize('NFKC', u' ̄')[1]) '0304' >>> '%04x' % ord(unicodedata.normalize('NFKD', u' ̄')[0]) '0020' >>> '%04x' % ord(unicodedata.normalize('NFKD', u' ̄')[1]) '0304'
互換文字の正規化
NFKC と NFC などの違いをみる:
>>> unicodedata.normalize('NFC', u'①') u'\u2460' >>> unicodedata.normalize('NFC', u'Ⅱ') u'\u2161' >>> unicodedata.normalize('NFD', u'①') u'\u2460' >>> unicodedata.normalize('NFD', u'Ⅱ') u'\u2161' >>> unicodedata.normalize('NFKC', u'①') u'1' >>> unicodedata.normalize('NFKC', u'Ⅱ') u'II' >>> unicodedata.normalize('NFKD', u'①') u'1' >>> unicodedata.normalize('NFKD', u'Ⅱ') u'II'
サロゲートペア
ちょっと脱線するがサロゲートペアの実験。
𦙾 d859de7e [ケイ] ケイコツノ ケイ:ニクヅキニ マタノシタ ツチ
出力するとコードポイント(32ビット)が得られるが、文字の長さは2文字になる:
>>> u'\ud859\ude7e' u'\U0002667e' >>> u'\ud859\ude7e'[0] u'\ud859' >>> u'\ud859\ude7e'[1] u'\ude7e'
ちなみにUTF-8では4バイトで表現される:
>>> len(u'\ud859\ude7e'.encode('utf-8')) 4
normalize の影響はない(NFC, NFD, NFKD でも同じ):
>>> unicodedata.normalize('NFKC', u'\ud859\ude7e') u'\U0002667e'