正規表現 - コンパイル時のフラグ、名前付きのグループ化、文字列の分割・置換

正規表現の振る舞いを変える

re.compile( )の第二引数にフラグを指定します。

>>> r1 = re.compile("[a-z]+=\d+", re.I) # 大文字と小文字を区別しない
>>> r1.findall("abc=123&DEF=456")
['abc=123', 'DEF=456']
>>>
>>> r2 = re.compile("a.+k", re.S)   # .を改行にもマッチさせる
>>> r3 = re.compile("^\s*$". re.M)  # ^を行頭に、$を行末にもマッチさせる
>>> r = re.compile(r"""(\d{4}) # 年
...                -(\d{1,2})  # 月
...                -(\d{1,2})  # 日
... """, re.X)                      # 空白を無視、コメントを書けるようにする
>>> r4 = re.compile(r"[a-z]", re.I | reS) # 複数のフラグを指定

名前付きのグループ化

( )にマッチした部分を番号ではなく名前で取り出すことができます。

>>> r = re.compile("(?P<year>\d{4})-"
...                "(?P<month>\d{1,2})-"
...                "(?P<day>\d{1,2})")
>>> m = r.search("1984-03-24")
>>> m.group("year")
'1984'
>>> m.group("month", "day")
('03', '24')
>>> m.group(1)    # 番号でも取り出せる
'1984'
>>> m.groupdict() # 辞書で取り出す
{'year': '1984', 'day': '24', 'month': '03'}

文字列の分割

>>> string = "a   b\tc\nd"
>>> re.compile("\s+").split(string)   # 1文字以上の空白でstringを分割
['a', 'b', 'c', 'd']
>>>
>>> re.compile("(\s+)").split(string) # ()があれば、()にマッチした部分も含まれる
['a', '   ', 'b', '\t', 'c', '\n', 'd']

文字列の置換

>>> string = "a  b   c   d"
>>> re.compile("\s+").sub(" ", string)    # 1文字以上の空白を' 'に置換
'a b c d'
>>> re.compile("\s+").sub(" ", string, 2) # 2番目にマッチした部分を置換
'a b c   d'


\1は1番目の( )に、\gは(?...)にマッチした部分に置き換えられます。

>>> r = re.compile("(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})")
>>> print r.sub(r"\1年\2月\3日", "2004-11-15")
20041115日
>>> print r.sub(r"\g<year>年\g<month>月\g<day>日", "2004-11-15")
20041115


置換文字列の代わりに関数を指定すると、MatchObjectのインスタンスが関数に渡されます。

>>> string = "python ruby perl"
>>> re.compile(r"\b(\w)").sub(lambda x:x.group(1).upper(), string)
'Python Ruby Perl'