Python : 正規表現の使い方

TwitterFacebookHatena
  • 公開:2021-10-20
  • 更新:2023-10-26
  • 文章量:3604
  • Python

TL;DR

正規表現はテキストの一部にマッチさせることのできるパターンである。メタ文字と呼ばれる記号を利用し、文字列の検索パターンを表すことができる。任意の文字列の中からパターンに合致する文字列を抽出したり置換を行う。Python では正規表現機能は、標準ライブラリの re モジュールによって提供されているのでインポートして使う。

正規表現の意味とマッチ例

汎用的な正規表現は次のようなものがある。

| パターン | 意味 | 使用例 | マッチ | | -------- | ------------------------------- | ---------------- | ----------------------- | -------------- | -------------- | | . | 改行を除く全ての 1 文字にマッチ | .ython | python, Python | | ^ | 文字列の先頭 | ^... | 行の先頭から 3 文字まで | | $ | 文字列の末尾 | ...$ | 末尾までの 3 文字 | | * | 直前の正規表現が 0 以上繰り返し | p*ython | ython で終わる全て | | + | 直前の正規表現が 1 以上繰り返し | p+ython | python | | ? | 直前の正規表現が 0 回、or 1 回 | Py?thon | Python, CPython | | | | いずれかの文字列 | Python | python | Python, python | | () | グルーピング | (Py | py)thon | Python, python | | [] | 括弧内の一文字 | [yponthP] | Python, CPython, python | | {} | 括弧内に繰り返し数 | p{2} | ppython |

特殊文字

パターン マッチ
\d 1 個の数字
\D 1 個の数字以外
\w 1 個の英単語
\W 1 個の英単語以外
\s 1 個の空白文字
\S 1 個の空白文字以外
\b 単語の境界
\B 単語の境界以外

文字セット

文字セットを使うと対象を制限することができる。範囲を指定するときは-、否定を指定するときは ^ を使う。

パターン 意味 マッチ
python(?=Love) Love が続いている python pythonLove
python(?!Love) Love が続いていない python Lovepython
[a-z] 小文字の半角英文字 abcdef ghi jklmn
[A-Z] 大文字の半角英文字 aBcdefG hiJk
[0-9] 半角数字を含む 0120 - 123 の 4567
[^0-9] 半角数字以外を含む 0123 の 123
[a-zA-Z0-9] 半角小文字大文字数字 abcABC012 123
[ぁ-ん] ひらがな あいうえお
[ァ-ヴ] カタカナ カキクケコ
<.*?> html タグ

^https?://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$ url https://~

例えば「.」は、改行を除くすべての一文字にマッチするので、.ython とした場合、python, Python, CPython にマッチする。

「猫は哺乳類である。」というテキストにマッチさせたい場合は、は.*である。というように組み合わせて使う。

正規表現の基礎をおさらいしたところで、Python の 正規表現機能について解説する。

re モジュール

Python においての正規表現機能は re モジュールによって提供されている。

match()はソースの先頭がパターンにマッチするか調べ、seach() は任意の位置でパターンを探す。

関数一覧

関数 関数の説明
match 先頭がパターンにマッチするか調べる
search 任意の位置でパターンを調べる。最初のマッチを返す
split パターンの出現で区切ってリストを返す
findall 全てのパターンのリストを返す
sub パターンを置換して返す
compile 正規表現の文字列からパターンオブジェクトを作る
escape すべての正規表現用特殊文字をエスケープする

match() による文字列の先頭のマッチ

.* は任意の個数の任意の文字という意味。次のコードでは、match() により .*Man にマッチした文字列 'Young Man' が返されている。

import re
result = re.match(r'.*Man', 'Young Man')
if result:
    print(result.group())
# Young Man

sub() による置換

sub()を使って置換することができる。次のコードでは、空白を _ に置き換えている。

import re
text = 'There is always light behind the clouds.'
rep = re.sub(r'\s', '_', text)
print(rep)

# There_is_always_light_behind_the_clouds.

split() による分割

次のコードでは、数字・アルファベット以外の文字で分割し、リストに格納している。

import re
text = 'Once you stop learning, you start-dying.'
rep = re.split(r'[^a-zA-Z0-9]+', text)
print(rep)

# ['Once', 'you', 'stop', 'learning', 'you', 'start', 'dying', '']

findall() を使ってすべてのマッチを検索

findall()は与えられたパターンに一致したすべての部分のリストを返す。次に示すコードは、文字の中に b という一文字の文字列が何個存在するのか調べるものである。

import re
text = 'If you want to be happy, be.'
result = re.findall(r'b', text)
print(len(result))

# 2

次に示すコードは、文字列中の全ての単語をリストに格納している。

import re
text = 'Once you stop learning, you start-dying.'
find = re.findall(r'[a-zA-Z]+', text)
print(find)

# ['Once', 'you', 'stop', 'learning', 'you', 'start', 'dying']

escape()を使ってエスケープする

escape() は、正規表現の演算子として解釈される全ての文字をエスケープする。

import re
text = 'docs.python.org/ja/3/library/functions.html#bool'
esc = re.escape(text)
print(esc)

# docs\.python\.org/ja/3/library/functions\.html\#bool

Python : 正規表現の使い方