Unicodeでは、一部の文字の組み合わせに複数の表現があります。
たとえば、文字äは次のように表すことができます。
c3 a4
(UTF-8エンコーディング)、またはas61 cc 88
(UTF-8)。Unicode標準によれば、2つの表現は同等ですが、異なる「正規化形式」です。 AX#15:Unicode正規化形式 を参照してください。
UNIXツールボックスには、すべての種類のテキスト変換ツール、sed、trがあります、iconv、Perlが思い浮かびます。コマンドラインですばやく簡単にNF変換を行うにはどうすればよいですか?
Pythonの標準ライブラリにはunicodedata
モジュールがあり、unicodedata.normalize()
関数を使用してUnicode表現を変換できます。
import unicodedata
s1 = 'Spicy Jalape\u00f1o'
s2 = 'Spicy Jalapen\u0303o'
t1 = unicodedata.normalize('NFC', s1)
t2 = unicodedata.normalize('NFC', s2)
print(t1 == t2)
print(ascii(t1))
t3 = unicodedata.normalize('NFD', s1)
t4 = unicodedata.normalize('NFD', s2)
print(t3 == t4)
print(ascii(t3))
Python 3.xで実行:
$ python3 test.py
True
'Spicy Jalape\xf1o'
True
'Spicy Jalapen\u0303o'
PythonはShell one linersにはあまり適していませんが、外部スクリプトを作成したくない場合は、次のように実行できます。
$ python3 -c $'import unicodedata\nprint(unicodedata.normalize("NFC", "ääääää"))'
ääääää
Python 2.xの場合、エンコーディングライン(# -*- coding: utf-8 -*-
)およびu文字を含むUnicodeとして文字列をマークします。
$ python -c $'# -*- coding: utf-8 -*-\nimport unicodedata\nprint(unicodedata.normalize("NFC", u"ääääää"))'
ääääää
完全を期すため、Perl
を使用します。
$ Perl -CSA -MUnicode::Normalize=NFD -e 'print NFD($_) for @ARGV' $'\ue1' | uconv -x name
\N{LATIN SMALL LETTER A}\N{COMBINING ACUTE ACCENT}
$ Perl -CSA -MUnicode::Normalize=NFC -e 'print NFC($_) for @ARGV' $'a\u301' | uconv -x name
\N{LATIN SMALL LETTER A WITH ACUTE}
Hexdumpツールで確認してください:
echo -e "ä\c" |hexdump -C
00000000 61 cc 88 |a..|
00000003
iconvで変換し、hexdumpで再度確認します。
echo -e "ä\c" | iconv -f UTF-8-MAC -t UTF-8 |hexdump -C
00000000 c3 a4 |..|
00000002
printf '\xc3\xa4'
ä
coreutilsには、適切なunorm
を取得するためのパッチがあります。 4バイトのwcharで私にとってはうまくいきます。従う http://crashcourse.housegordon.org/coreutils-multibyte-support.html#unorm 2バイトのwcharシステム(cygwin、windows、および32ビットのaixとsolaris)の残りの問題コードポイントを上位プレーンからサロゲートペアに、またはその逆に変換する必要があり、基になるlibunistring/gnulibはまだそれを処理できません。
Perlにはunichars
ツールがあり、cmdlineでさまざまな正規化形式も実行します。 http://search.cpan.org/dist/Unicode-Tussle/script/unichars
から利用可能なCharlintと呼ばれるPerlユーティリティがあります。
https://www.w3.org/International/charlint/
あなたがやりたいことをします。また、からファイルをダウンロードする必要があります
ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
最初の実行後、Charlintがそのファイルの互換性のないエントリについて不平を言っているのがわかるので、UnicodeData.txtからそれらの行を削除する必要があります。