📝
全角英数字を半角に変換
全角英数字を半角に変換したい時、javascriptでは以下のようにします。
str.replace(/[0-9a-zA-Z]/g, function (s) {
return String.fromCharCode(s.charCodeAt(0) - 0xfee0);
});
pythonで同じことをする方法を探していたらUnicode正規化
という言葉を見付けました。
例えばzennではtopics
を指定することができます。ユーザーによってはpython(半角)
をpython(全角)
と書く人がいるかもしれません。そうなるとpython(半角)
とpython(全角)
は別のtopicsになってしまいます。
このような重複をなくすためにUnicode正規化
すると、ユーザーが入力したpython(全角)
はpython(半角)
に修正されます。
そしてpythonの標準ライブラリであるunicodedata
を使うと簡単に正規化することができます。
import unicodedata
s = "123①②③,㍻㍉㌦㎡㈱№,abcABC,Å🅱©,123abcABC,<>,アイウエオカキクケコ"
unicodedata.normalize("NFKC", s)
# '123123,平成ミリドルm2(株)No,abcABC,Å🅱©,123abcABC,<>,アイウエオカキクケコ'
変換前 | 変換後 | 備考 |
---|---|---|
123①②③, | 123123 | 全角数字と機種依存文字 |
㍻㍉㌦㎡㈱№ | 平成ミリドルm2(株)No | 機種依存文字 |
abcABC | abcABC | 全角英字 |
Å🅱© | Å🅱© | 英字の記号 |
123abcABC | 123abcABC | 半角英数字(変わらず) |
<> | <> | 記号 |
アイウエオカキクケコ | アイウエオカキクケコ | カタカナ |
全角英数字だけでなく、機種依存文字や括弧、半角カタカナも変換されています。
normalize関数の引数に指定したNFKC
は正規化の形式で、以下4つから選べます。
s = "123①②③,㍻㍉㌦㎡㈱№,abcABC,Å🅱©,123abcABC,<>,アイウエオカキクケコ"
[
unicodedata.normalize("NFC", s),
unicodedata.normalize("NFKC", s),
unicodedata.normalize("NFD", s),
unicodedata.normalize("NFKD", s),
]
['123①②③,㍻㍉㌦㎡㈱№,abcABC,Å🅱©,123abcABC,<>,アイウエオカキクケコ',
'123123,平成ミリドルm2(株)No,abcABC,Å🅱©,123abcABC,<>,アイウエオカキクケコ',
'123①②③,㍻㍉㌦㎡㈱№,abcABC,Å🅱©,123abcABC,<>,アイウエオカキクケコ',
'123123,平成ミリドルm2(株)No,abcABC,Å🅱©,123abcABC,<>,アイウエオカキクケコ']
Discussion
C形式とD形式は見た目からは違いが分からないようです。
以下のコードスニペットのようにバイナリで表現すると判別出来ました。
(C形式はアクセント文字を1つの文字として保持しているのに対し、D形式は元の文字とアクセントの2文字として保持しているようです)