この記事では、正規表現を使う方法をソースコード付きで解説します。
正規表現とは
正規表現とは、「文字列のパターンを示した式」です。
通常、文字列を探索する場合は、「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入門 基本文法 |
コメント
「searchのサンプルコード」に間違いがあります。
print( matchObj.start() ) # 一致した開始位置を表示
は
print( match_data.start() ) # 一致した開始位置を表示
です。
※通りすがり 様
いつもコメントありがとうございます。
ご指摘いただいた通り、誤りでしたので該当箇所を修正しました。
今後ともよろしくお願いします。
print( match_data.span() ) # (3, 7):一致した位置を表示のspan(3, 7)の意味を教えて下さい。
pythonを初めて一カ月目の初心者です。宜しくお願いいたします。
※渡邉様
コメントありがとうございます。
span()は、一致した部分文字列の開始位置と終了位置を求めます。
(3, 7)は「3~6番目の文字列と一致」であることを意味しています。
※0番目始まりに注意
「data = ‘abcdefghijklmnabcdefghijklmn’」ですので
3~6番目の文字列は「d~g」となります。