home changes contents help options

073:正規表現を分割して記述する

re.compile などに渡す正規表現は通常の文字列に違いないので、たとえば次のように組み立てることができます。

import re

regex1 = 'aaa'
regex2 = 'bbb'
regex = re.compile('%s|%s' % (regex1, regex2))

複数の正規表現オブジェクトから新たな正規表現を組み立てたいこともあるかと思います。正規表現オブジェクトは自身が作成される際に用いられた文字列を pattern 属性に保持しています。これを利用すると、次のようなことが可能です。

import re
regex1 = re.compile('aaa')
regex2 = re.compile('bbb')
regex = re.compile('%s|%s' % (regex1.pattern, regex2.pattern))

文字列の埋め込みを % 演算子ではなく Python 2.6 以降で使える format メソッドで行うと次のようになります。

import re
regex1 = re.compile('aaa')
regex2 = re.compile('bbb')
regex = re.compile('{0}|{1}'.format(regex1.pattern, regex2.pattern))

文字列のつなぎ方に一工夫してみます。% 演算子、 format メソッドともに順序ベースではなく名前ベースの埋め込みができますので、次のようにすることができます。

regex = re.compile(
    '%(a)s|%(b)s' % dict(
                        a=regex1.pattern, b=regex2.pattern))
regex = re.compile(
    '{a}|{b}'.format(a=regex1.pattern, b=regex2.pattern))

format メソッド単なる文字列埋め込みにとどまらず、テンプレートとしての機能も持ち合わせています。 属性名を大本となる文字列のほうに入れることができます。すると、引数のほうには正規表現オブジェクトを渡すだけとなります。

regex = re.compile(
    '{a.pattern}|{b.pattern}'.format(a=regex1, b=regex2))

大本となる文字列、引数双方に名前 (今回は a, b) を書くのが無駄に感じたなら、 locals 関数を使ってみるのも面白いでしょう。

regex = re.compile(
    '{regex1.pattern}|{regex2.pattern}'.format(**locals()))

参考