この記事では、Python の reモジュール の使い方を解説します。
re
モジュール を使うことで正規表現を使った文字列の取得、分割、置換を行うことができます。正規表現を使うので複雑な文字列にも対応可能です。
正規表現については以下の記事を参考にしてください。
re
モジュール は、標準ライブラリです。インポートするだけで使えます。
import re
それでは、re
モジュール の使い方を見ていきましょう❗️
マッチオブジェクトの取得
文字列にパターン(正規表現)がマッチすれば、対応したマッチオブジェクトが返されます。マッチオブジェクトについては後述します。
先頭のマッチ[re.match]
re.match(pattern, string, flags=0)
string(文字列)
の先頭で pattern(正規表現)
にマッチすれば、対応するマッチオブジェクトを返します。
import re
match = re.match('abc', 'abcabc')
print(f'マッチした箇所: {match.group()}')
>> マッチした箇所: abc
先頭でなければマッチしない。
import re
match = re.match('bc', 'abcabc')
print(f'マッチした箇所: {match.group()}')
>> AttributeError: 'NoneType' object has no attribute 'group'
最初のマッチ[re.search]
re.search(pattern, string, flags=0)
string(文字列)
の最初に pattern(正規表現)
にマッチした箇所に対応するマッチオブジェクトを返します。
import re
match = re.search('abc', 'abcabc')
print(f'マッチした箇所: {match.group()}')
>> マッチした箇所: abc
もちろん、先頭以外の箇所でもマッチします。
import re
match = re.search('bc', 'abcabc')
print(f'マッチした箇所: {match.group()}')
>> マッチした箇所: bc
全体のマッチ[re.fullmatch]
re.fullmatch(pattern, string, flags=0)
string(文字列)
の全体が pattern(正規表現)
にマッチすれば、対応するマッチオブジェクトを返します。Python 3.4 で追加。
import re
match = re.fullmatch('abc', 'abc')
print(f'マッチした箇所: {match.group()}')
>> マッチした箇所: abc
一箇所でも違えばマッチしません。
import re
match = re.fullmatch('ab', 'abc')
print(f'マッチした箇所: {match.group()}')
>> AttributeError: 'NoneType' object has no attribute 'group'
全ての重複しないマッチをイテレータで返す[re.finditer]
re.finditer(pattern, string, flags=0)
string(文字列)
中の重複しないマッチに対応した全てのマッチオブジェクトをイテレータとして返します。
import re
matchs = re.finditer('abc', 'abcabc')
# イテレータとして返されるのでfor文で処理
for i, match in enumerate(matchs, 1):
print(f'{i}回目のマッチ: {match.group()}')
>> 1回目のマッチ: abc
>> 2回目のマッチ: abc
マッチオブジェクト
マッチオブジェクトの bool
値 は True
です。なので、マッチしたかどうかは以下のように簡単に判定できます。
import re
match = re.match(pattern, string)
if match:
# マッチオブジェクト有り
マッチした文字列を取得する
group()
メソッド を使うことでマッチした箇所の文字列を取得することができます。
import re
match = re.match('.+=.+', 'age=20')
print(f'マッチした箇所: {match.group()}')
# >> マッチした箇所: age=20
# 引数に0を指定しても同じ
print(f'マッチした箇所: {match.group(0)}')
>> マッチした箇所: age=20
グループ化してある場合は、引数にグループのインデックスを指定することでグループごとに取得することができます。
import re
match = re.match('(.+)=(.+)', 'age=20')
print(match.group(1), match.group(2))
>> age 20
# 複数の引数を指定することで、まとめてタプルとして取得可能
print(match.group(1, 2))
>> ('age', '20')
グループにグループ名が指定されている場合は、グループ名を指定することで対応した文字列を取得することができます。
import re
match = re.match('(?P<section>.+)=(?P<value>.+)', 'age=20')
print(match.group('section'), match.group('value'))
>> age 20
groupdict()
メソッド を使うことでグループ名を key
、マッチを value
として格納した辞書を取得できます。
import re
match = re.match('(?P<section>.+)=(?P<value>.+)', 'age=20')
print(match.groupdict())
>> {'section': 'age', 'value': '20'}
groups()
メソッド を使えば、マッチしたグループ全てをタプルとして取得できる。
import re
match = re.match('(.+)=(.+)', 'age=20')
print(f'グループ: {match.groups()}')
>> グループ: ('age', '20')
match = re.match('(.+)=(.+)?', 'age=')
# マッチしなかったグループにはNoneが返される
print(f'グループ: {match.groups()}')
>> グループ: ('age', None)
# 引数でデフォルト値を指定できる
print(f'グループ: {match.groups(0)}')
>> グループ: ('age', 0)
マッチのインデックス
マッチした箇所の先頭のインデックスを start()
メソッド、末尾のインデックスを end()
メソッド で取得することができます。
import re
match = re.match('(.+)=(.+)', 'age=20')
print(f'マッチ: {match.group()}, 先頭: {match.start()}, 末尾: {match.end()}')
>> マッチ: age=20, 先頭: 0, 末尾: 6
引数でグループを指定することができます。
print(f'マッチ: {match.group(1)}, 先頭: {match.start(1)}, 末尾: {match.end(1)}')
>> マッチ: age, 先頭: 0, 末尾: 3
print(f'マッチ: {match.group(2)}, 先頭: {match.start(2)}, 末尾: {match.end(2)}')
>> マッチ: 20, 先頭: 4, 末尾: 6
span()
メソッド で先頭と末尾のインデックスを保持したタプルを受け取ることができます。こちらのメソッドも引数でグループを指定可能です。
import re
match = re.match('(.+)=(.+)', 'age=20')
print(f'マッチ: {match.group()}, span: {match.span()}')
>> マッチ: age=20, span: (0, 6)
print(f'マッチ: {match.group(1)}, span: {match.span(1)}')
>> マッチ: age, span: (0, 3)
print(f'マッチ: {match.group(2)}, span: {match.span(2)}')
>> マッチ: 20, span: (4, 6)
全てのマッチを文字列のリストで返す
re.findall()
メソッド を使うことで全てのマッチを文字列のリストと取得できます。
re.findall(pattern, string, flags=0)
string(文字列)
中のマッチした文字列をリストとして返します。
import re
matchs = re.findall('abc', 'abcabcabc')
print(matchs)
>> ['abc', 'abc', 'abc']
正規表現オブジェクト
正規表現オブジェクトをコンパイルすることで そのオブジェクトから match()
メソッド や sertch()
メソッド を呼び出すことが可能となります。
同じパターンで何度も処理をしたい場合には、正規表現オブジェクトを生成し、再利用した方が効率的です。
正規表現オブジェクトをコンパイルするには re.compile()
メソッド を使います。
re.compile(pattern, flags=0)
例えば、このようなコードは、
obj = re.compile(pattern)
result = obj.search(string)
以下のコードと同等です。
result = re.search(pattern, string)
パターンで分割
re.split()
メソッド は、マッチした箇所で分割することができます。
re.split(pattern, string, maxsplit=0, flags=0)
マッチした部分は消えちゃうので注意しましょう。
import re
s = re.split('\W', 'abc,abc,abc')
print(f'リザルト: {s}')
>> マッチした箇所: ['abc', 'abc', 'abc']
maxsplit
を指定することで最大分割回数を指定することができます。
import re
s = re.split('\W', 'abc,abc,abc', 1)
print(f'リザルト: {s}')
>> リザルト: ['abc', 'abc,abc']
パターンで置換
re.sub()
メソッド は、マッチした箇所を指定した文字列に置換することができます。
re.sub(pattern, repl, string, count=0, flags=0)
repl
に置換する文字列を指定します。
import re
s = re.sub('\W', '-', 'abc,abc,abc')
print(f'リザルト: {s}')
>> リザルト: abc-abc-abc
count
引数 を指定することで置換する回数を指定できます。
import re
s = re.sub('\W', '-', 'abc,abc,abc', count=1)
print(f'リザルト: {s}')
# >> リザルト: abc-abc,abc
まとめ
この記事では、Python の reモジュール の使い方を解説しました。
正規表現を使うことで複雑な文字列に合わせて色々できます。
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ