正規表現の基礎

入門Python3 7.1.3


正規表現についてです。

python正規表現はなにやらいろいろメソッドがあったりして把握が大変なのでとにかく御託はいいから一番シンプルな使い方はなんなのってことで実装してみます。

str1 = "abcdefg"
result  = re.search('cde',str1)
if result:
    print("match!")
$ py main.py
match!

abcdefgにcdeという文字列が含まれているかどうかを確認するだけの処理です。

またこの他にre.compileをつかって先に正規表現コンパイルしてから利用するやり方もあります。

import re
regex = re.compile('cde') # あらかじめコンパイル

str1 = "abcdefg"
result = regex.search(str1)
if result:
    print("match!")
$ py main.py
match!

検索の仕方

さて先ほどsearchというメソッドを使用しましたが他にも検索のためのメソッドが存在します。

ドキュメントにあるように良く使われる4つのメソッドについて確認してみます。

メソッド/属性 目的
match() 文字列の先頭で正規表現とマッチするか判定します。
search() 文字列を操作して、正規表現がどこにマッチするか調べます。
findall() 正規表現にマッチする部分文字列を全て探しだしリストとして返します。
finditer() 正規表現にマッチする部分文字列を全て探しだし iterator として返します。

matchは単にsearchの時に「^」で先頭でマッチさせるならまったく同じ意味になるかんじなんですかね。

matchとsearchはヒットしなければNoneが返り、ヒットすればMatchオブジェクトを返します。

Matchオブジェクトでよく使われそうなものとして以下のメソッドの確認をしてみます。

メソッド/属性 目的
group() 正規表現にマッチした文字列を返す
group(x) 正規表現にマッチした()でグループ化した部分の文字列を返す
groups() 正規表現にマッチした()でグループ化した部分の文字列をタプルで全て返す
start() マッチの開始位置を返す
end() マッチの終了位置を返す
span() マッチの位置 (start, end) を含むタプルを返す
import re
str1 = "abcdefg"
r  = re.search('(c)(de)',str1)
if r:
    print(r.group())  # cde
    print(r.group(1)) # c
    print(r.group(2)) # de
    print(r.groups()) # ('c', 'de')
    print(r.start())  # 2
    print(r.end())    # 5
    print(r.span())   # (2, 5)
$ py main.py
cde
c
de
('c', 'de')
2
5
(2, 5)


次はfindallについて。これはマッチした部分の文字列が全てリストで返ってくるというもの。

import re
str1 = "ab11cde22fg34"
r  = re.findall('\d+',str1) # 数値にマッチ
if r:
    print(r)
$ py main.py
['11', '22', '34']


次はfinditerについて。findallと似ているがリストではなくイテレータを返すところが違う。

また各要素にはMatchオブジェクトが返る。

import re
str1 = "aa1bb2cc3bb4"
r  = re.finditer('bb(\d+)',str1) # 「bb数値」にマッチ
if r:
    for item in r:
        print(item.group())
        print(item.group(1))
        print(item.groups())
        print(item.start())
        print(item.end())
        print(item.span())
        print('--')
$ py main.py
bb2
2
('2',)
3
6
(3, 6)
--
bb4
4
('4',)
9
12
(9, 12)
--

findallだとグループ化が効かないので基本的にはこのfinditerを使った方が便利かなという印象ですね。