文法・環境 組み込み関数

【Python】正規表現の基本的な使用方法【reモジュール】

Pythonにおいて、文字列を検索する際に、正規表現を使用する方法について、紹介します。

本記事では、以下の内容を紹介しています。

この記事で分かること

  • 正規表現とは
  • 正規表現の基本的な使用方法

◆reモジュールの関数について◆

  • match( ) : 文字列の先頭がマッチするか判定
  • search( ) : 先頭に限らずマッチするか判定
  • fullmatch( ) : 文字列全体がマッチするか判定
  • findall( ) : マッチした文字列をリストで取得
  • finditer( ) : マッチした文字列をイテレータで取得
  • sub( ) : マッチした文字列を置換
  • split( ) : パターンで文字列を分割

◆メタ文字の使用例◆

  • . : 任意の1文字
  • * : 直前のパターンを0回以上繰り返し
  • + : 直前のパターンを1回以上繰り返し
  • ? : 直前のパターンを0回または1回繰り返し
  • {m} : 直前のパターンをm回繰り返し
  • {m,n} : 直前のパターンをm~n回繰り返し
  • [ ] : 文字の集合を指定
  • ( ) : グループ化
  • A|B : AかBのどちらか
  • ^ : 文字列の先頭
  • $ : 文字列の末尾

スポンサーリンク

正規表現とは

正規表現とは、文字列をパターンで表現する記述方法です。

正規表現を用いることで、指定したパターンに当てはまる文字列を検索することができます

Pythonの標準ライブラリである、"reモジュール"を用いることで、正規表現を扱うことができます。

以降の項で、Pythonにおける正規表現の基本的な使用方法について、紹介します。

スポンサーリンク

【Python】正規表現の基本的な使用方法

Pythonにおける、正規表現の基本的な使用方法について紹介します。

以下の3つについて、順番に紹介します。

  • reモジュールで使用できる関数について
  • 正規表現のメタ文字について
  • マッチオブジェクトについて

reモジュールで使用できる関数について

Pythonの標準ライブラリである、"reモジュール"を用いることで、正規表現を扱うことができます。

reモジュールには、使用できる関数が複数あり、文字列パターンの検索方法を指定できます

reモジュールで使用できる関数としては、次のものがあります。

関数説明
match( )文字列の先頭がマッチするか判定
search( )先頭に限らずマッチするか判定
fullmatch( )文字列全体がマッチするか判定
findall( )マッチした文字列をリストで取得
finditer( )マッチした文字列をイテレータで取得
sub( )マッチした文字列を置換

正規表現のメタ文字について

検索する文字列のパターンは、"メタ文字"を用いて指定します

Pythonの "reモジュール" で使用できるメタ文字には、次のものがあります。

メタ文字説明指定例マッチする例マッチしない例
.任意の1文字
(改行は含まない)
a.cabc,acc,a1cabb,abbc
*直前のパターンを0回以上繰り返しab*a,ab,abbaa,bb
+直前のパターンを1回以上繰り返しab+ab,abba,aa,bb
?直前のパターンを0または1回繰り返しab?a,ababb
{m}直前のパターンをm回繰り返しa{2}aaa,aaa
{m,n}直前のパターンをm~n回繰り返しa{2,3}aa,aaaa,aaaa
[ ]文字の集合を指定。[ ]内に指定した文字のうち、どれかを含む[a-c]a,b,cd,e,f
( )グループ化(abc)+abc,abcabca,ab
A | BAかBのどちらかのパターンa|ba,bc,d
^文字列の先頭^abcabcdefdefabc
$文字列の末尾abc$defabcabcdef

この表以外にも使用できるメタ文字があります。

詳細は、Pythonの公式ドキュメントを参考にしてみてください。

マッチオブジェクトについて

reモジュールの関数であるmatch( )やsearch( )は、マッチオブジェクトを返します

マッチオブジェクトのメソッドを実行することで、マッチした文字列や位置を取得できます

Pythonのマッチオブジェクトのメソッドには、次のものがあります。

メソッド説明
start( )マッチした文字列の開始位置を取得
end( )マッチした文字列の終了位置を取得
span( )マッチした文字列の開始位置と終了位置を取得
group( )マッチした文字列を取得

正規表現の基本的な使用例

正規表現の基本的な使用例を紹介します。

以下、match( )関数を用いて文字列を検索するサンプルコードです。

### match()関数で検索
import re

s = r'abcde, 12345, a123e'
res = re.match(r'a...e', s)

print(type(res))
# <class 're.Match'>

print(res)
# <re.Match object; span=(0, 5), match='abcde'>

print(res.start())
#0

print(res.group())
#abcde

> res = re.match(r'a…e', s)

reモジュールのmatch( )関数を用いて、パターン "a...e" に一致する文字列を検索しています。

> print(type(res))
> # <class 're.Match'>

変数 res はマッチオブジェクトです。

> print(res.start())
> #0

マッチオブジェクトのメソッドstart()を用いて、文字列の開始位置を取得しています。

> print(res.group())
> #abcde

マッチオブジェクトのメソッドgroup()を用いて、マッチした文字列を取得しています。

スポンサーリンク

reモジュールの関数の使用方法

ここからは、reモジュールの関数について、サンプルコードを交えながら紹介します。

以下の関数の使用方法について、順番に紹介します。

  • match( ) : 文字列の先頭がマッチするか判定
  • search( ) : 先頭に限らずマッチするか判定
  • fullmatch( ) : 文字列全体がマッチするか判定
  • findall( ) : マッチした文字列をリストで取得
  • finditer( ) : マッチした文字列をイテレータで取得
  • sub( ) : マッチした文字列を置換
  • split( ) : パターンで文字列を分割

match( ) : 文字列の先頭がマッチするか判定

match( )関数は、文字列の先頭がパターンにマッチするかを判定する関数です。

書き方

re.match( パターン, 検索対象の文字列 )

以下、サンプルコードです。

import re

s = r'abcde, 12345, a123e'
res = re.match(r'a...e', s)

print(res)
# <re.Match object; span=(0, 5), match='abcde'>

文字列の先頭がパターンと一致しない場合には、"None" が返されます。

import re

s = r'12345, abcde, a123e'
res = re.match(r'a...e', s)

print(res)
# None

search( ) : 先頭に限らずマッチするか判定

search( )関数は、文字列がパターンにマッチするかを判定する関数です。

match( )関数とは異なり、文字列の先頭に限らずパターンとマッチするか判定できます。

書き方

re.search( パターン, 検索対象の文字列 )

以下、サンプルコードです。

import re

s = r'abcde, 12345, a123e'
res = re.search(r'a...e', s)

print(res)
# <re.Match object; span=(0, 5), match='abcde'>

文字列の先頭以外でも、パターンにマッチするか判定されます。

import re

s = r'12345, abcde, a123e'
res = re.search(r'a...e', s)

print(res)
# <re.Match object; span=(7, 12), match='abcde'>

fullmatch( ) : 文字列全体がマッチするか判定

fullmatch( )関数は、文字列全体がパターンにマッチするかを判定する関数です。

書き方

re.fullmatch( パターン, 検索対象の文字列 )

以下、サンプルコードです。

import re

s = r'abcde'
res = re.fullmatch(r'a...e', s)

print(res)
# <re.Match object; span=(0, 5), match='abcde'>

検索対象の文字列が、1字でもパターンと異なる場合には、"None"が返されます。

import re

s = r'abcdef'
res = re.fullmatch(r'a...e', s)

print(res)
# None

スポンサーリンク

findall( ) : マッチした文字列をリストで取得

findall( )関数を用いることで、マッチした文字列をリストで取得することができます。

書き方

re.findall( パターン, 検索対象の文字列 )

以下、サンプルコードです。

import re

s = r'abcde, 12345, a123e'
res = re.findall(r'a...e', s)

print(res)
# ['abcde', 'a123e']

文字列の先頭以外でも、パターンにマッチするか判定されます。

import re

s = r'12345, abcde, a123e'
res = re.findall(r'a...e', s)

print(res)
# ['abcde', 'a123e']

finditer( ) : マッチした文字列をイテレータで取得

finditer( )関数を用いることで、マッチした文字列をイテレータで取得することができます。

書き方

re.finditer( パターン, 検索対象の文字列 )

イテレータは、そのままprint( )を用いただけでは、中身を確認できません。

for文を用いて、1つずつ取り出すことで、中身を確認できます。

以下、サンプルコードです。

import re

s = r'abcde, 12345, a123e'
res = re.finditer(r'a...e', s)

print(res)
# <callable_iterator object at 0x0000025F80C43978>

for r in res :
    print(r)
# <re.Match object; span=(0, 5), match='abcde'>
# <re.Match object; span=(14, 19), match='a123e'>

文字列の先頭以外でも、パターンにマッチするか判定されます。

import re

s = r'12345, abcde, a123e'
res = re.finditer(r'a...e', s)

print(res)
# <callable_iterator object at 0x0000024BA82E22B0>

for r in res :
    print(r)
# <re.Match object; span=(7, 12), match='abcde'>
# <re.Match object; span=(14, 19), match='a123e'>

findall( )関数では、一致した文字列のみ取得できましたが、
finditer( )関数では、一致した文字列の位置も併せて取得できます。

sub( ) : マッチした文字列を置換

sub( )関数を用いることで、マッチした文字列を置換できます。

書き方

re.sub( パターン, 置換後の文字列, 検索対象の文字列, 最大置換個数)

最大置換個数は省略可能です。

以下、サンプルコードです。

import re

s = r'abcde, 12345, a123e'
res = re.sub(r'a...e', r'xxx', s)

print(res)
# xxx, 12345, xxx

文字列の先頭以外でも、パターンにマッチするか判定されます。

import re

s = r'12345, abcde, a123e'
res = re.sub(r'a...e', r'xxx', s)

print(res)
# 12345, xxx, xxx

最大置換個数を1個指定したサンプルコードです。

import re

s = r'abcde, 12345, a123e'
res = re.sub(r'a...e', r'xxx', s, 1)

print(res)
# xxx, 12345, a123e

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

split( )関数を用いることで、パターンで文字列を分割できます。

書き方

re.split( パターン, 検索対象の文字列, 最大分割個数)

最大分割個数は省略可能です。

以下、サンプルコードです。

import re

s = r'123abcde456a123e789'
res = re.split(r'a...e', s)

print(res)
# ['123', '456', '789']

スポンサーリンク

メタ文字の使用例

ここからは、正規表現で使用できるメタ文字について、サンプルコードを交えながら使用方法を紹介します。

下表のメタ文字について、順番に紹介します。

メタ文字説明指定例マッチする例マッチしない例
.任意の1文字
(改行は含まない)
a.cabc,acc,a1cabb,abbc
*直前のパターンを0回以上繰り返しab*a,ab,abbaa,bb
+直前のパターンを1回以上繰り返しab+ab,abba,aa,bb
?直前のパターンを0または1回繰り返しab?a,ababb
{m}直前のパターンをm回繰り返しa{2}aaa,aaa
{m,n}直前のパターンをm~n回繰り返しa{2,3}aa,aaaa,aaaa
[ ]文字の集合を指定。[ ]内に指定した文字のうち、どれかを含む[a-c]a,b,cd,e,f
( )グループ化(abc)+abc,abcabca,ab
A | BAかBのどちらかのパターンa|ba,bc,d
^文字列の先頭^abcabcdefdefabc
$文字列の末尾abc$defabcabcdef

. : 任意の1文字

以下、サンプルコードです。

import re

s = r'abc, acc, abbc'
res = re.findall(r'a.c', s)

print(res)
# ['abc', 'acc']

"abbc" は、aとcの間に2文字あるので、パターンには一致しません。

* : 直前のパターンを0回以上繰り返し

以下、サンプルコードです。

import re

s = r'a, b, ab, aa, bb, abb, aab'
res = re.findall(r'ab*', s)

print(res)
# ['a', 'ab', 'a', 'a', 'abb', 'a', 'ab']

+ : 直前のパターンを1回以上繰り返し

以下、サンプルコードです。

import re

s = r'a, b, ab, aa, bb, abb, aab'
res = re.findall(r'ab+', s)

print(res)
# ['ab', 'abb', 'ab']

? : 直前のパターンを0回または1回繰り返し

以下、サンプルコードです。

import re

s = r'a, b, ab, aa, bb, abb, aab'
res = re.findall(r'ab?', s)

print(res)
# ['a', 'ab', 'a', 'a', 'ab', 'a', 'ab']

{m} : 直前のパターンをm回繰り返し

以下、サンプルコードです。

import re

s = r'a, b, ab, aa, bb, abb, aab, aaa, aaaa'
res = re.findall(r'a{2}', s)

print(res)
# ['aa', 'aa', 'aa', 'aa', 'aa']

{m,n} : 直前のパターンをm~n回繰り返し

以下、サンプルコードです。

import re

s = r'a, b, ab, aa, bb, abb, aab, aaa, aaaa'
res = re.findall(r'a{2,3}', s)

print(res)
# ['aa', 'aa', 'aaa', 'aaa']

[ ] : 文字の集合を指定

以下、サンプルコードです。

import re

s = r'123abcde456a123e789'
res = re.findall(r'[a-z]+', s)

print(res)
# ['abcde', 'a', 'e']

ハイフン'-'を用いると、文字や数値の範囲を指定できます。

[a-z]+ とすることで、aからzまでの小文字のアルファベットのうちいずれか を、1回以上繰り返す という意味になります。

こちらは、3~5回繰り返された小文字のアルファベットを抽出するサンプルコードです。

import re

s = r'123abcde456a123e789'
res = re.findall(r'[a-z]{3,5}', s)

print(res)
# ['abcde']

( ) : グループ化

以下、サンプルコードです。

import re

s = r'123abcabc456abc789abcabcabc123'
res = re.finditer(r'(abc)+', s)

print(res)
# <callable_iterator object at 0x0000025F80D370F0>

for r in res :
    print(r)
# <re.Match object; span=(3, 9), match='abcabc'>
# <re.Match object; span=(12, 15), match='abc'>
# <re.Match object; span=(18, 27), match='abcabcabc'>  

(abc)+ とすることで、abcが1回以上繰り返された場合に、マッチするようになります。

A|B : AかBのどちらか

以下、サンプルコードです。

import re

s = r'aa ab, ac, bc, bb, cc'
res = re.finditer(r'(a|b)c', s)

print(res)
# <callable_iterator object at 0x0000025F80D37198>

for r in res :
    print(r)
# <re.Match object; span=(7, 9), match='ac'>
# <re.Match object; span=(11, 13), match='bc'>

^ : 文字列の先頭

"^"を記載することで、文字列の先頭がパターンに一致するかを判定できます。

import re

s = r'abcde12345'
res = re.search(r'^abc', s)

print(res)
# <re.Match object; span=(0, 3), match='abc'>

文字列の先頭がパターンに一致しない場合は、Noneが返されます。

import re

s = r'12345abcde'
res = re.search(r'^abc', s)

print(res)
# None

なお、" ^ "は、集合と併せて記述した場合は、補集合を表す記号になるので、注意してください。

import re

s = r'123abcde456a123e789'
res = re.findall(r'[^a-z]+', s)

print(res)
# ['123', '456', '123', '789']

$ : 文字列の末尾

"$"を記載することで、文字列の末尾がパターンに一致するかを判定できます。

import re

s = r'123abc'
res = re.search(r'abc$', s)

print(res)
# <re.Match object; span=(3, 6), match='abc'>

文字列の末尾がパターンに一致しない場合は、Noneが返されます。

import re

s = r'abc123'
res = re.search(r'abc$', s)

print(res)
# None

正規表現に関しては、他にも使用方法をまとめています。併せて参考にしてみてください。

【Python】正規表現の具体的な使用例【日付、電話番号、メールアドレス、URL】
【Python】正規表現の特殊シーケンスについて【バックスラッシュ、円マーク】
【Python】reモジュールのcompile関数の使い方
【Python】正規表現の貪欲・非貪欲マッチ

スポンサーリンク

-文法・環境, 組み込み関数
-,