Pythonの正規表現モジュールにおける日本語の扱いについて
Pythonは文字列をUnicodeで扱うことができるため、正規表現においても日本語を正しく扱うことができる。Python 2では処理時にパターンと入力文字列の両方をUnicode文字列にしておく必要がある。
Unicodeのコードによる指定を行うことにより、コード範囲による検索を行うこともできる。
下は対話モードでのテスト例。「<_sre.SRE_Match object」が出ているときに一致している。
Python 3の場合:
>>> import re >>> re.search ('[ぁ-ゞ]', 'test') (ひらがなが無いので一致せず、何も表示されない) >>> re.search ('[ぁ-ゞ]', 'testてすとtest') <_sre.SRE_Match object; span=(4, 5), match='て'>
Python 2の場合:
>>> import re >>> re.search (u'[ぁ-ゞ]', u'test') (ひらがなが無いので一致せず、何も表示されない) >>> re.search (u'[ぁ-ゞ]', u'testてすとtest') <_sre.SRE_Match object at 0x7f8f3a32a238> (以下、特定のエンコーディングの入力文字列・パターン文字列を それぞれUnicodeに変換後検索している unicode()の2番目の引数は元の文字列のエンコーディング) >>> str='testテストtest' >>> str_unicode = unicode(str, 'utf-8') >>> ptn='[ァ-ヾ]' >>> ptn_unicode = unicode(ptn, 'utf-8') >>> re.search(ptn_unicode, str_unicode) <_sre.SRE_Match object at 0x7f8f3a32a1d0>
(2015/1/7)Python 3でのテスト例を追加
「[ぁ-ゞ]」はUnicodeのコードにおける任意のひらがな1文字を示す。このあたりはGucharmapを使用して調べたものを
http://kakurasan.ehoh.net/software/pygtkrefs/doc/japanese.html
にまとめている。
また、上のテストでは簡単に書く目的で正規表現オブジェクトが再利用できないが、実際に使用する場合は「Pythonの正規表現モジュールにおけるコンパイルの効果を検証」のようにコンパイルしたパターンを使い回すのがよい。
(2012/4/1)re.search()の引数の誤りを修正した。バージョン2系のPythonではUnicodeでない文字列で処理をすると
#! /usr/bin/python # -*- coding: iso-2022-jp -*- # Python 2.x向け import re s='testテストtest' s_unicode = unicode (s, 'iso-2022-jp') p='[ァ-ヾ]' p_unicode = unicode (p, 'iso-2022-jp') print re.search (p_unicode, s_unicode) # OK print re.search (p, s) # sre_constants.error: bad character range
失敗する場合がある(Unicode文字列にしたものは正しく処理できる)。
<_sre.SRE_Match object at 0x7ff64ce63308> Traceback (most recent call last): File "[スクリプトの場所]", line 14, in <module> print re.search (p, s) # sre_constants.error: bad character range File "/usr/lib/python2.7/re.py", line 142, in search return _compile(pattern, flags).search(string) File "/usr/lib/python2.7/re.py", line 244, in _compile raise error, v # invalid expression sre_constants.error: bad character range
バージョン3系のPythonでは文字列は内部的にUnicode文字列となるため
#! /usr/bin/python # -*- coding: iso-2022-jp -*- # Python 3向け import re s='testテストtest' p='[ァ-ヾ]' print (re.search (p, s))
このような書き方で問題なく動作する。
使用したバージョン:
- Python 2.5.2, 2.7.2, 3.2.2, 3.4.2