PYTHON MEBY

Pythonで文字列をUnicode正規化(unicodedata.normalize)

この記事では、Pythonのunicodedata.normalize()関数を使用してUnicode文字列を正規化する方法を説明します。正規化フォーム、使用方法、そして実践的な例を通して、Unicode文字列の処理における正規化の重要性を理解します。

目次

Unicode正規化とは?

Unicode文字列は、同じ文字を表現する複数の方法が存在することがあります。これは、文字の結合方法や表現方法の違いによるものです。Unicode正規化とは、これらの異なる表現方法を統一された標準的な形に変換するプロセスです。これにより、文字列の比較や照合が容易になり、予期せぬバグを防ぐことができます。

例えば、同じ文字でも、合成済み文字と分解済み文字という異なる表現方法があります。正規化によって、これらを統一的な表現にできます。

print(unicodedata.normalize('NFC', 'cafe\u0301'))
print(unicodedata.normalize('NFC', 'cafe\u0301'))

正規化フォームの種類

unicodedata.normalize()関数は、以下の4種類の正規化フォームをサポートしています。

  • NFC (Normalization Form C): 合成済み文字を使用する正規化フォーム。最も一般的なフォームです。
  • NFD (Normalization Form D): 分解済み文字を使用する正規化フォーム。
  • NFKC (Normalization Form KC): 互換文字を考慮した合成済み文字を使用する正規化フォーム。
  • NFKD (Normalization Form KD): 互換文字を考慮した分解済み文字を使用する正規化フォーム。

unicodedata.normalize()の使い方

unicodedata.normalize()関数は、以下の引数を取ります。

  • form: 正規化フォームを表す文字列 ('NFC', 'NFD', 'NFKC', 'NFKD')
  • unicode_string: 正規化対象のUnicode文字列
import unicodedata

string = 'cafe\u0301'

nfc_string = unicodedata.normalize('NFC', string)
nfd_string = unicodedata.normalize('NFD', string)
fknc_string = unicodedata.normalize('NFKC', string)
fkd_string = unicodedata.normalize('NFKD', string)

print(f'元の文字列: {string}')
print(f'NFC: {nfc_string}')
print(f'NFD: {nfd_string}')
print(f'NFKC: {fknc_string}')
print(f'NFKD: {fkd_string}')

実践例

正規化は、文字列の比較やデータベースへの保存において重要です。異なる正規化フォームの文字列を比較すると、結果が異なる可能性があります。正規化を行うことで、このような問題を回避できます。

import unicodedata

string1 = 'a\u0300'
string2 = 'a\u0300'

print(f'string1 == string2: {string1 == string2}')
normalized_string1 = unicodedata.normalize('NFC', string1)
normalized_string2 = unicodedata.normalize('NFC', string2)
print(f'normalized_string1 == normalized_string2: {normalized_string1 == normalized_string2}')

上記例では、正規化をすることで比較結果が正しくなります。

注意点

  • 正規化フォームの選択は、用途によって適切なものを選ぶ必要があります。
  • NFCは、多くの場合、デフォルトの正規化フォームとして使用されます。
  • NFKCは、互換文字の扱い方に注意が必要です。

関連記事