Pythonで正規表現:グループ化を使ってみる

正規表現でマッチした文字列の全てに興味がある訳ではないことがしばしば起こる。例えば固定電話番号のマッチングでは市外局番・市内局番・加入者番号がマッチすることを要求するが興味があるのは加入者番号だけであるというようなばあいである。このばあいはマッチした文字列全体ではなく、加入者番号のみを表示すれば足りる。このようなばあいにグループ化が使える。

グループ化は(正規表現)とグループ化したい正規表現の部分を丸括弧()で括ってやる。グループ化は入れ子(表現1(表現2))でも直列(表現1)(表現2)でも構わない。グループには番号が振られる。正規表現全体はグループ0、正規表現を右に検索し左丸括弧に出会うと番号はインクリメントし、対応する右丸括弧までがこのグループに所属することになる。実例を示す:


#coding: utf-8
import re
telNumber = re.compile(r"""
^0    #ゼロ発信
(
    #固定電話(市外・市内・加入者)
      [36]-\d{4}- (\d{4})  #東京(3)・大阪(6)
    | \d{2}-\d{3}- (\d{4}) #仙台(22)
    | \d{3}-\d{2}- (\d{4]) #松本(263)
    | \d{4}-\d-    (\d{4}) #伊豆大島(4992)
    #携帯電話(キャリア・管轄・加入者)
    | [7-9]0-\d{3} (\d-\d{4})    
)
""", re.VERBOSE)

m=telNumber.search('022-345-9876')
if m :
    print(m.groups())
else:
    print(m)

この例では正規表現に六個のグループが使われている。メソッドgroups()はこの六個のグループに対応する表示をタプルの形で取り出すことができる。この実例の結果は

('22-345-9876', None, '9876', None, None, None)

グループ1とグループ3でマッチする表現があることが分る。Noneは該当するグループにマッチする文字列がなかったことを意味する。

このグループ化のPython拡張としてグループに名前を付けることができる。それには(?P<名前>…)というふうに左丸括弧の次に?P<名前>を挿入する。実例を示す:


#coding: utf-8
import re
telNumber = re.compile(r"""
^0    #ゼロ発信
(?P<電話番号>
    #固定電話(市外・市内・加入者)
      [36]-\d{4}- (?P<固定0>\d{4})  #東京(3)・大阪(6)
    | \d{2}-\d{3}- (?P<固定1>\d{4}) #仙台(22)
    | \d{3}-\d{2}- (?P<固定2>\d{4]) #松本(263)
    | \d{4}-\d-    (?P<固定3>\d{4}) #伊豆大島(4992)
    #携帯電話(キャリア・管轄・加入者)
    | [7-9]0-\d{3} (?P<携帯>\d-\d{4})    
)
""", re.VERBOSE)

m=telNumber.search('070-2345-9876')
if m :
    print(m.groupdict())
else:
    print(m)

メソッドgroupdict()によってグループ名をキーとしマッチした文字列を値とする辞書で結果を取り出すことができる。結果は

{'電話番号': '70-2345-9876','固定0': None,'固定1': None,
 '固定2': None, '固定3': None, '携帯': '5-9876'}

となり、この電話番号は携帯で加入者番号が5-9876であることが表示される。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です