Pythonにおける正規表現

Pythonにおける正規表現

この記事ではPythonにおける正規表現について説明します。

reモジュールの基本的な使い方から、複雑な正規表現のパターンマッチングまで、幅広くカバーします。

YouTube Video

Pythonにおける正規表現

reモジュールは、正規表現を使用して文字列の検索や操作を行うために使用されます。

reモジュールとは

reモジュールは、Python標準ライブラリに含まれており、正規表現を使って文字列操作を行う機能を提供します。正規表現は、特定の文字列パターンを効率的に見つけたり、抽出したり、置換したりするために使用されます。

基本的な正規表現パターン

正規表現は、特殊な記号を使ってパターンを定義します。以下に、いくつかの基本的なパターンを示します。

  • .: 任意の1文字
  • ^: 文字列の先頭
  • $: 文字列の末尾
  • \d: 任意の数字 (0-9)
  • \w: 任意の単語文字 (a-z, A-Z, 0-9, _)
  • \s: 任意の空白文字
  • *: 0回以上の繰り返し
  • +: 1回以上の繰り返し
  • []: 文字クラス(例えば [a-z] は小文字のアルファベットにマッチ)
 1import re
 2
 3pattern = r"\d{3}-\d{4}"
 4text = "My postal code is 123-4567."
 5result = re.search(pattern, text)
 6if result:
 7    print(result.group())  # Output: 123-4567
 8
 9# Define a pattern using basic regular expression symbols
10pattern = r"^\w+\s\d+\s[a-zA-Z]+$"
11
12# Example text to test the pattern
13text = "Room 23 Tokyo"
14
15# Check if the pattern matches the text
16result = re.match(pattern, text)
17if result:
18    print("Matched:", result.group())
19else:
20    print("No match")
  • このコードでは、最初に郵便番号のパターンにマッチするかを確認しています。次に、文字列の先頭から末尾まで、単語・空白・数字・空白・英単語という構成を持つパターンにマッチするかを確認しています。正規表現の基本要素がどのように組み合わさるかを理解する助けになります。

マッチング関数の使い方

re.match()

re.match()は、文字列の先頭が指定したパターンに一致するかどうかを調べます。

1import re
2
3pattern = r"\w+"
4text = "Python is powerful"
5match = re.match(pattern, text)
6if match:
7    print(match.group())  # Output: Python
  • このコードは、文字列の先頭が単語文字(英数字やアンダースコア)で始まるかを確認しています。最初の単語「Python」がパターンに一致し、出力されます。

re.search()

re.search()は、文字列全体を検索して、最初にマッチする部分を返します。

1import re
2
3pattern = r"powerful"
4text = "Python is powerful and versatile"
5search = re.search(pattern, text)
6if search:
7    print(search.group())  # Output: powerful
  • このコードは、文字列全体の中から「powerful」という単語を検索し、最初に見つかった部分を返します。結果として、re.search()はマッチした文字列「powerful」を出力します。

re.findall()

re.findall()は、パターンに一致する全ての部分をリストで返します。

1import re
2
3pattern = r"\b\w{6}\b"
4text = "Python is powerful and versatile"
5matches = re.findall(pattern, text)
6print(matches)  # Output: ['Python', 'strong']
  • このコードは、6文字ちょうどの単語をすべて検索し、リストとして返します。文字列中の「Python」が条件に一致し、リスト ['Python'] が出力されます。

re.finditer()

re.finditer()は、パターンに一致するすべての部分をイテレータとして返し、それぞれの一致について詳細な情報を取得できます。

1import re
2
3pattern = r"\b\w{6}\b"
4text = "Python is powerful and versatile"
5matches = re.finditer(pattern, text)
6for match in matches:
7    print(match.group())  # Output: Python
  • このコードは、6文字の単語をすべて順に検索し、各一致部分をイテレータとして処理します。ここでは「Python」がパターンに一致し、出力されます。

置換と分割

re.sub()

re.sub()は、正規表現に一致する部分を別の文字列に置換します。

1import re
2
3pattern = r"\d+"
4text = "There are 100 apples"
5new_text = re.sub(pattern, "many", text)
6print(new_text)  # Output: There are many apples
  • このコードは、文字列中のすべての数字を「many」に置き換えています。

re.split()

re.split()は、正規表現に一致する部分で文字列を分割します。

1import re
2
3pattern = r"\s+"
4text = "Python is powerful"
5parts = re.split(pattern, text)
6print(parts)  # Output: ['Python', 'is', 'powerful']
  • このコードは、1つ以上の空白文字で文字列を分割しています。結果として、文字列が単語ごとに分割され、['Python', 'is', 'powerful'] が得られます。

グループとキャプチャ

正規表現のグループ化を使うと、マッチした部分文字列を簡単に取得できます。カッコ () で囲むと、グループとしてキャプチャされます。

1import re
2
3pattern = r"(\d{3})-(\d{4})"
4text = "My postal code is 123-4567."
5match = re.search(pattern, text)
6if match:
7    print(match.group(1))  # Output: 123
8    print(match.group(2))  # Output: 4567
  • このコードは、郵便番号の形式「123-4567」から3桁と4桁の数字をそれぞれ別のグループとして抽出します。group(1) は最初の3桁「123」、group(2) は後半の4桁「4567」を返します。

名前付きグループ

名前付きグループを使うと、インデックスに頼らずに意味のある名前で値を取得できます。以下はログから日付とレベルを抽出する具体例です。

1import re
2
3log = "2025-10-25 14:00:01 [ERROR] Something failed"
4
5pattern = r"(?P<date>\d{4}-\d{2}-\d{2}) (?P<time>\d{2}:\d{2}:\d{2}) \[(?P<level>[A-Z]+)\] (?P<msg>.*)"
6m = re.search(pattern, log)
7if m:
8    print(m.group("date"), m.group("time"), m.group("level"))
9    print("message:", m.group("msg"))
  • このコードは、名前付きグループを使ってログ文字列から日付・時刻・レベル・メッセージを抽出します。インデックスではなく、意味のある名前を使って値を取得しています。

フラグオプションの使用

reモジュールには、検索を制御するためのいくつかのフラグオプションがあります。

  • re.IGNORECASE (re.I): 大文字と小文字を区別しないフラグオプションです。
  • re.MULTILINE (re.M): 複数行にわたってマッチするフラグオプションです。
  • re.DOTALL (re.S): ドット . が改行文字にもマッチするフラグオプションです。
1import re
2
3pattern = r"python"
4text = "Python is powerful"
5match = re.search(pattern, text, re.IGNORECASE)
6if match:
7    print(match.group())  # Output: Python
  • このコードは、大文字と小文字を区別せずに「python」という単語を検索します。re.IGNORECASE フラグを使用することで、「Python」にもマッチします。

正規表現オブジェクト(re.compile)の利点

パターンを re.compile すると再利用に効率的で、読みやすくなります。フラグもここで設定できます。

次の例はコンパイル済みパターンで複数行から一致を繰り返し探す例です。頻繁に同じパターンを使う場合は re.compile しておくとパフォーマンスが向上します。

1import re
2
3pattern = re.compile(r"User: (\w+), ID: (\d+)")
4text = "User: alice, ID: 1\nUser: bob, ID: 2"
5
6for m in pattern.finditer(text):
7    print(m.groups())
  • このコードは、コンパイル済みの正規表現を使って複数行からユーザー名とIDを抽出します。re.compile により同じパターンを繰り返し使う際の効率が向上し、コードも読みやすくなります。

応用例

例えば、テキストファイルからすべてのメールアドレスを抽出するスクリプトを考えてみます。

1import re
2
3pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
4text = "Contact us at info@example.com or support@service.com."
5emails = re.findall(pattern, text)
6print(emails)  # Output: ['info@example.com', 'support@service.com']
  • このコードは、文字列中のすべてのメールアドレスを検索してリストとして抽出します。

結論

reモジュールは、Pythonでの文字列操作において非常に強力なツールです。ここでは、基本的な使い方から、グループ化やフラグオプションを使った高度な正規表現まで幅広く解説しました。Pythonの正規表現は非常に強力で、テキスト処理において不可欠なツールです。

YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。

YouTube Video