「使い倒すための正規表現」で正規表現についてまとめましたが、今回はそれを応用してPythonで正規表現を使い倒していきます。
- 対象読者
- Pythonでの正規表現の使い方がわからない方
- 「そもそも正規表現って何?」という方はこちら
- 内容
- 正規表現の基本事項を理解できる(メタ文字、特殊シーケンス)
- Pythonのreモジュールの使い方
- 実践的な正規表現の使い方
- 実行環境
- Windows 10
- Python 3.6
前回のおさらいがてら、下の表を眺めておいてください。
メタ文字 | 説明 | 例 | マッチする文字列 |
---|---|---|---|
. | 任意の1文字 | a.c | abc, acc |
^ | 文字列の先頭 | ^abc | abcde |
$ | 文字列の末尾 | abc$ | dabc |
* | 直前の文字を0回以上繰り返し | ab* | a, ab, abb, abbb |
+ | 直前の文字を1回以上繰り返し | ab+ | ab, abb, abbb |
? | 直前の文字を1回以下繰り返し | ab? | a, ab |
{n} | 直前の文字をn回繰り返し | a{3} | aaa |
{m,n} | 直前の文字をm〜n回繰り返し | a{2, 4} | aa, aaa, aaaa |
[] | 指定した文字の中のいずれの文字 | [a-c] | a, b, c |
[^] | 指定した文字以外 | [^a] | b, c |
| | いずれかの文字列 | a|b | a, b |
() | グループ化 | (abc)+ | abc, abcabc |
よく使われる正規表現のパターンは\(バックスラッシュ)で始まる「特殊シーケンス」を使うことで、記述が楽になります。
特殊シーケンス | 説明 | 正規表現で表すと… |
---|---|---|
\d | 任意の数字 | [0-9] |
\D | 任意の数字以外 | [^0-9] |
\s | 任意の空白文字 | [\t\n\r\f\v] |
\S | 任意の空白文字以外 | [^\t\n\r\f\v] |
\w | 任意の英数字 | [a-xA-Z0-9_] |
\W | 任意の英数字以外 | [\a-xA-Z0-9_] |
\A | 文字列の先頭 | ^ |
\Z | 文字列の末尾 | $ |
Pythonで正規表現
Pythonで正規表現を扱うには、reモジュールをimportします。
ちょっとしたコツなんですが、正規表現を事前にコンパイルしておいた方が処理が高速になります。(繰り返し回数が多い処理の時に効果を発揮しますよ!)
また、文字列のかっこの前にrをつけておくことで、文字列内の\(バックスラッシュ)を\(バックスラッシュ)として認識することができるようになります。
コンパイルするバージョン
import re
regex = r"\d年\d組.{4}先生"
text = "3年B組きんぱち先生 1年2組くろやぎ先生"
pattern = re.compile(regex)
matchObject = pattern.search(text)
print(matchObject)
# <_sre.SRE_Match object; span=(11, 21), match='1年2組くろやぎ先生'>
コンパイルしないバージョン
import re
regex = r"\d年\d組.{4}先生"
text = "3年B組きんぱち先生 1年2組くろやぎ先生"
matchObject = re.search(regex, text)
print(matchObject)
# <_sre.SRE_Match object; span=(11, 21), match=’1年2組くろやぎ先生’>
reモジュールの関数
関数(’正規表現’, ‘文字列’) | 目的 |
---|---|
match(regex, text) | 先頭が一致する文字列抽出 |
search(regex, text) | 全体の中で一致する最初の文字列抽出 |
findall(regex, text) | 全体の中で一致する文字全て抽出 |
match関数
match関数は、検索対象の文字列の先頭に抽出ワードが存在するか判定します。
第一引数に抽出する正規表現、第二引数に検索対象の文字列を指定します。
対象が存在しない場合はNoneを返し、存在する場合はmatchオブジェクトが返ります。
import re
regex = '.{3}:[0-9]{3}円'
text = "りんご:100円 みかん:50円"
matchObject = re.match(regex, text)
print(matchObject)
# <_sre.SRE_Match object; span=(0, 8), match='りんご:100円'>
import re
regex = '.{3}:[0-9]{2}円'
text = "りんご:100円 みかん:50円"
matchObject = re.match(regex, text)
print(matchObject)
# None
よく使うであろうmatchオブジェクトのメソッドは以下の4つです。
メソッド/属性 | 目的 |
---|---|
group() | 正規表現にマッチした文字列を返す。 |
start() | マッチの開始位置を返す。 |
end() | マッチの終了位置を返す。 |
span() | マッチの位置 (start, end) を含むタプルを返す。 |
search関数
search関数は検索対象の文字列の先頭から最後までを検索し、抽出ワードが存在するか判定します。
import re
regex = r'.{3}:[0-9]{2}円'
text = "りんご:100円 みかん:50円"
matchObject = re.search(regex, text)
print(matchObject)
# <_sre.SRE_Match object; span=(9, 16), match='みかん:50円'>
findall関数
findall関数は検索対象の文字列の先頭から最後までを検索し、存在する正規表現の全てを取得して文字列のリストで返します。
import re
regex = '.{3}:[0-9]+円'
text = "りんご:100円 みかん:50円"
matchList = re.findall(regex, text)
print(matchList)
# ['りんご:100円', 'みかん:50円']
findメソッド
findメソッドは文字列型のメソッドで、文字列を検索するときに使用します。
引数に渡した文字列が存在すれば、そのインデックス(リストや辞書の中の要素の位置)を返します。
検索した対象が存在しない場合は、”-1″を返します。
text = "オレンジ、みかん、グレープフルーツ、レモン"
str_find = text.find('みかん')
print(str_find)
# 5
インデックスは0から始まるため、”みかん”の文字の始まり”み”の位置が、先頭の0文字目から数えて5文字目という結果が得られます。
おわりに
HTML内の特定のタグの検索などは、よく使う機能なので(Web関係の職業の人しか使わない気がするけどw)、習得しておくと今後の自分のためになるはずです。