Python

【Python】reモジュールの使い方

この記事では、Pythonのreモジュールの使い方を解説します。

reモジュールを使うことで、正規表現を使った文字列の取得、分割、置換を行うことができます。正規表現を使うので、複雑な文字列にも対応可能です。

正規表現については以下の記事を参考にしてください。

【Python】正規表現の使い方この記事では、Pythonで正規表現を使う方法を解説します。世界にはいろんな数字や文字で溢れいていますが、文字のパターンによってそれが何...

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(正規表現)にマッチすれば、対応するマッチオブジェクトを返します。Python3.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

マッチオブジェクト

マッチオブジェクトのブール値は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モジュールの使い方を解説しました。

正規表現を使うことで複雑な文字列に合わせて色々できます。

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

最短3か月でエンジニア転職『DMM WEBCAMP COMMIT』