試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

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