Pythonの正規表現モジュールreの関数match、search、sub

Pythonには正規表現の操作を提供するモジュールreが用意されています。

6.2. re — 正規表現操作 — Python 3.6.1 ドキュメント

ここでは、正規表現の複雑なパターンは使わず、以下のreモジュールの関数およびコンパイル済み正規表現のメソッドの振る舞いを説明します。

文字列の先頭がパターンにマッチするかを調べるmatch() 先頭に限らずパターンにマッチするかを調べるsearch() マッチする部分すべてをリストで返すfindall() マッチする部分すべてをイテレータで返すfinditer() マッチした部分を置換するsub()、subn() パターンで文字列を分割するsplit() 正規表現オブジェクトをコンパイルするcompile()

まず、reをインポートしてソースとなる文字列を準備します。 import re

s = 'one two one two'

文字列の先頭がパターンにマッチするかを調べるmatch()

re.match()は文字列の先頭がパターンにマッチするかどうかを調べる。

m = re.match('one', s)
print(m)
# <_sre.SRE_Match object; span=(0, 3), match='one'>

マッチする場合はmatchオブジェクトを返します。matchオブジェクトはgroup()、start()、end()、span()などのメソッドを持ち、マッチした文字列やその位置などを返します。

6.2.4. match オブジェクト — Python 3.6.1 ドキュメント

print(m.group())
print(m.start())
print(m.end())
print(m.span())
# one
# 0
# 3
# (0, 3)

group()メソッドはパターンにマッチした全体を返すが、パターンの一部分を()で囲んでおくと、groups()メソッドを使って、()で囲まれた部分にマッチしたそれぞれの文字列をタプルで取得できます。

m = re.match('(one) (two)', s)
print(m)
print(m.group())
print(m.groups())
# <_sre.SRE_Match object; span=(0, 7), match='one two'>
# one two
# ('one', 'two')

先頭にマッチする文字列がない場合はNoneを返します。

m = re.match('two', s)
print(m)
# None

先頭に限らずパターンにマッチするかを調べるsearch()

re.search()は先頭にない文字列も探すことができます。re.match()と同じく、マッチする場合はmatchオブジェクトを返します。

m = re.search('one', s)
print(m)
# <_sre.SRE_Match object; span=(0, 3), match='one'>

m = re.search('two', s)
print(m)
# <_sre.SRE_Match object; span=(4, 7), match='two'>

文字列中にマッチする部分が複数あっても、返すのは最初にマッチした部分のみ。

マッチする部分すべてをリストで返すfindall()

re.findall()は、マッチする部分が複数ある場合、マッチした文字列すべてをリストにして返します。返すのはmatchオブジェクトではないので気をつけてください。

m = re.findall('one', s)
print(m)
# ['one', 'one']

m = re.findall('one two', s)
print(m)
# ['one two', 'one two']

マッチする部分すべてをイテレータで返すfinditer()

re.finditer()はマッチする部分すべてをmatchオブジェクトのイテレータで返します。ただのリストを返すre.findall()とは違い、matchオブジェクトを得られるので、マッチした位置なども取得することができます。

m = re.finditer('one', s)
print(m)
# <callable_iterator object at 0x10e786470>

for match in m:
    print(match)
# <_sre.SRE_Match object; span=(0, 3), match='one'>
# <_sre.SRE_Match object; span=(8, 11), match='one'>

マッチした部分を置換するsub()、subn()

re.sub()を使うと、マッチした部分を他の文字列に置換することができます。

m = re.sub('one', 'ONE', s)
print(m)
# ONE two ONE two

m = re.sub('one two', 'xxx', s)
print(m)
# xxx xxx

パターンの一部を()で囲むと、置換後の文字列の中でマッチした文字列を使用することができます。

m = re.sub('(one) (two)', '\\1X\\2', s)
print(m)
# oneXtwo oneXtwo

m = re.sub('(one) (two)', r'\1X\2', s)
print(m)
# oneXtwo oneXtwo

\1、\2が、それぞれ一つ目の()にマッチした部分と二つ目の()にマッチした部分に対応しています。''または""で囲まれた通常の文字列だと\1のように\をエスケープする必要があるが、r''のように先頭にrをつけるraw文字列の場合は\1で問題ありません。 置換後の文字列と置換された部分の個数とのタプルで返すre.subn()関数もあります。

m = re.subn('one', 'ONE', s)
print(m)
# ('ONE two ONE two', 2)

文字列の置換についての詳細は

パターンで文字列を分割するsplit()

re.split()はパターンにマッチした部分で文字列を分割し、リストにして返します。

m = re.split(' ', s)
print(m)
# ['one', 'two', 'one', 'two']

文字列の分割についての詳細は

正規表現オブジェクトをコンパイルするcompile()

同じパターンを繰り返し使用する場合は、re.compile()で、あらかじめパターンをコンパイルして正規表現オブジェクトを生成したほうがよい。 正規表現オブジェクトのメソッドとして、上で紹介したmatch()やsub()などを使うことができます。

p = re.compile('one')

m = p.match(s)
print(m)
# <_sre.SRE_Match object; span=(0, 3), match='one'>

m = p.findall(s)
print(m)
# ['one', 'one']

m = p.sub('ONE', s)
print(m)
# ONE two ONE two
Last Updated: 6/26/2019, 10:34:03 PM