【Python】正規表現の使い方 (reモジュール)

この記事では、正規表現を使う方法をソースコード付きで解説します。

正規表現とは

正規表現とは、「文字列のパターンを示した式」です。
通常、文字列を探索する場合は、「hello」や「100」などと直接単語や数値を検索します。
しかし、この方法では例えば「5桁以上の数値」というように複雑な場合は探せません。
このような場合に、正規表現を使うと簡単に検索パターンを作って探すことができます。
本記事では、Pythonとreモジュールを用いた正規表現の使い方を紹介します。

正規表現のパターン式

正規表現の代表的なパターン式は以下の通りです。

パターン式 内容
[ ] [ ] 内に指定した文字のどれかと一致
[^ ] [ ] 内に指定した文字でない場合に一致する
^ 行頭と一致
$ 行末と一致
. 任意の1文字と一致
( ) 正規表現をグループにまとめる
| 前後にある正規表現のいずれかと一致
+ 直前の正規表現の1回以上の繰り返しに一致
? 直前の正規表現に0回 or 1回一致
{m,n} 直前の正規表現のm~n回の繰り返しに一致
+? 直前の正規表現の1回以上の繰り返しに一致
*? 直前の正規表現の0回以上の繰り返しに一致
?? 直前の正規表現に0回もしくは1回一致
* 直前の正規表現の0回以上の繰り返しに一致
{m,n}? 直前の正規表現のm~n回の繰り返しに一致
\ メタ文字を打ち消す
\A 文字列の先頭と一致
\b 単語境界と一致 (\w と \W の間の空文字列と一致)
\B \B 以外と一致
\d 数字と一致 ( [0-9] と同じ )
\D \d以外と一致
\s 空白文字と一致
\S \s 以外と一致
\w 英数字とアンダースコア_に一致
\W \w 以外と一致
\Z 文字列の末尾と一致

例えば、hel[lL]oと書くと、helloとhelLoを探索します。
このように正規表現のパターン式を用いることで、複雑なパターンを簡単に記述できます。

reモジュールで正規表現

Pythonの標準モジュールreでは、パターン式と一致するデータを探すための関数としてmatch()、search()、findall()、finditer()の4種類が用意されています。
Pythonとreを用いた正規表現による探索のサンプルコードを紹介します。

matchのサンプルコード

match()は、文字列の先頭でパターンが一致するかを判定します。

# -*- coding: utf-8 -*-
import re

data = 'abcdefghijklmn'
pattern = re.compile(r'a.*?c') # パターン式の定義(aで始まりcで終わる最短の文字列)
match_data = pattern.match(data)# パターン式との一致判定

print( match_data.group() )  # abc

searchのサンプルコード

search()は、パターンと一致する部分があるかどうかを判定します。
一致する部分が複数ある場合は、最初の部分のみ返します。
(matchとの違いは、文字列の先頭でなくても一致の判定をします)

# -*- coding: utf-8 -*-
import re

data = 'abcdefghijklmnabcdefghijklmn'
pattern = re.compile(r'd.*?g') # パターン式の定義(dで始まりgで終わる最短の文字列)
match_data = pattern.search(data)# パターン式との一致判定

print( match_data.group() )  # defg:一致したデータ
print( match_data.start() ) # 3:一致した開始位置
print( match_data.end() )  # 7:一致した終了位置
print( match_data.span() )  # (3, 7):一致した位置を表示

findallのサンプルコード

findall()は、パターンと一致するすべての部分を判定します。
(search()との違いは、一致した箇所をすべて取得します)
注意点としては、探索結果をオブジェクトでなく配列(リスト)で返します。

# -*- coding: utf-8 -*-
import re

data = 'abcdefghijklmnabcdefghijklmn'
pattern = re.compile(r'd.*?g') # パターン式の定義(dで始まりgで終わる最短の文字列)
match_data = pattern.findall(data)# パターン式との一致判定

print( match_data )  # ['defg', 'defg']一致したデータ

finditerのサンプルコード

finditerは、パターンと一致する部分を判定します。
これさえあれば、上の3つの関数でできることはすべてできます。


# -*- coding: utf-8 -*-
import re

data = 'abcdefghijklmnabcdefghijklmn'
pattern = re.compile(r'd.*?g') # パターン式の定義(dで始まりgで終わる最短の文字列)
match_datas = pattern.finditer(data)# パターン式との一致判定

for match in match_datas:
    print( match.group() )  # 一致したデータ
    print( match.start() ) # 一致した開始位置
    print( match.end() )  # 一致した終了位置
    print( match.span() )  # 一致した位置

"""
実行結果
defg
3
7
(3, 7)
defg
17
21
(17, 21)
"""
関連記事
1 【Python入門】文字列の処理・使い方
2 Python入門 基本文法

コメント

  1. 通りすがり より:

    「searchのサンプルコード」に間違いがあります。

    print( matchObj.start() ) # 一致した開始位置を表示

    print( match_data.start() ) # 一致した開始位置を表示
    です。

    • 管理人 より:

      ※通りすがり 様
      いつもコメントありがとうございます。
      ご指摘いただいた通り、誤りでしたので該当箇所を修正しました。
      今後ともよろしくお願いします。

  2. 渡邉豊 より:

    print( match_data.span() ) # (3, 7):一致した位置を表示のspan(3, 7)の意味を教えて下さい。
    pythonを初めて一カ月目の初心者です。宜しくお願いいたします。

    • 管理人 より:

      ※渡邉様

      コメントありがとうございます。
      span()は、一致した部分文字列の開始位置と終了位置を求めます。

      (3, 7)は「3~6番目の文字列と一致」であることを意味しています。
      ※0番目始まりに注意

      「data = ‘abcdefghijklmnabcdefghijklmn’」ですので
      3~6番目の文字列は「d~g」となります。