[Python] 正規表現でパターンに合う文字列を抽出する方法
Pythonで正規表現を使用してパターンに合う文字列を抽出するには、標準ライブラリのre
モジュールを使用します。
主にre.findall()
、re.search()
、re.match()
が使われます。
re.findall()
は、パターンに一致するすべての部分文字列をリストで返し、re.search()
は最初に一致した部分文字列を返します。
re.match()
は文字列の先頭から一致するかを確認します。
正規表現パターンはr'パターン'
の形式で指定します。
- Pythonの正規表現の基本的な使い方
- メタ文字や特殊シーケンスの活用法
- 高度な正規表現のテクニック
- 文字列抽出の具体的な実例
- 正規表現のオプション設定の方法
Pythonで正規表現を使う方法
Pythonで正規表現を扱うためには、標準ライブラリのre
モジュールを使用します。
このモジュールを使うことで、文字列のパターンマッチングや抽出、置換などが簡単に行えます。
reモジュールのインポート
まず、正規表現を使用するためにre
モジュールをインポートします。
import re
re.findall()でパターンに一致する文字列を抽出
re.findall()関数
は、指定したパターンに一致するすべての文字列をリストとして返します。
import re
text = "私のメールアドレスは example@example.com です。"
pattern = r'\w+@\w+\.\w+'
result = re.findall(pattern, text)
print(result)
['example@example.com']
この例では、メールアドレスの形式に一致する部分を抽出しています。
re.search()で最初に一致する文字列を抽出
re.search()関数
は、指定したパターンに最初に一致する部分を見つけ、その情報を持つマッチオブジェクトを返します。
import re
text = "私の電話番号は 090-1234-5678 です。"
pattern = r'\d{3}-\d{4}-\d{4}'
match = re.search(pattern, text)
if match:
print(match.group())
090-1234-5678
この例では、電話番号の形式に一致する最初の部分を抽出しています。
re.match()で文字列の先頭から一致を確認
re.match()関数
は、文字列の先頭からパターンに一致するかどうかを確認します。
import re
text = "Pythonは楽しいプログラミング言語です。"
pattern = r'Python'
match = re.match(pattern, text)
if match:
print("一致しました:", match.group())
else:
print("一致しませんでした。")
一致しました: Python
この例では、文字列の先頭が Python
で始まるかどうかを確認しています。
re.finditer()で一致する部分をイテレータで取得
re.finditer()関数
は、指定したパターンに一致する部分をイテレータとして返します。
これにより、マッチオブジェクトを逐次処理できます。
import re
text = "abc123def456ghi789"
pattern = r'\d+'
matches = re.finditer(pattern, text)
for match in matches:
print(match.group())
123
456
789
この例では、数字の部分をすべて抽出しています。
re.sub()でパターンに一致する部分を置換
re.sub()関数
は、指定したパターンに一致する部分を別の文字列に置換します。
import re
text = "私の電話番号は 090-1234-5678 です。"
pattern = r'\d{3}-\d{4}-\d{4}'
replacement = "XXX-XXXX-XXXX"
result = re.sub(pattern, replacement, text)
print(result)
私の電話番号は XXX-XXXX-XXXX です。
この例では、電話番号を XXX-XXXX-XXXX
に置換しています。
正規表現の基本的なパターン
正規表現では、特定のパターンに基づいて文字列を検索・抽出するためのさまざまなメタ文字や特殊シーケンスが用意されています。
これらを理解することで、より複雑なパターンマッチングが可能になります。
メタ文字の使い方
メタ文字は、正規表現の中で特別な意味を持つ文字です。
以下に代表的なメタ文字を紹介します。
. (任意の1文字)
.
は任意の1文字にマッチします。
改行文字以外のすべての文字に一致します。
import re
text = "abc, a1c, a-c"
pattern = r'a.c'
result = re.findall(pattern, text)
print(result)
['abc', 'a1c', 'a-c']
^ (行頭)
^
は文字列の先頭にマッチします。
行の最初に特定の文字列があるかどうかを確認するのに使います。
import re
text = "Pythonは楽しい\nJavaも楽しい"
pattern = r'^Python'
match = re.search(pattern, text, re.MULTILINE)
if match:
print("一致しました:", match.group())
一致しました: Python
$ (行末)
$
は文字列の末尾にマッチします。
行の最後に特定の文字列があるかどうかを確認するのに使います。
import re
text = "Pythonは楽しい\nJavaも楽しい"
pattern = r'楽しい$'
match = re.search(pattern, text, re.MULTILINE)
if match:
print("一致しました:", match.group())
一致しました: 楽しい
[] (文字クラス)
[]
を使うことで、指定した文字のいずれか1文字にマッチします。
import re
text = "apple, banana, cherry"
pattern = r'[ab]anana'
result = re.findall(pattern, text)
print(result)
['banana']
| (OR条件)
|
を使うことで、複数のパターンのいずれかにマッチします。
import re
text = "猫と犬が好きです。"
pattern = r'猫|犬'
result = re.findall(pattern, text)
print(result)
['猫', '犬']
繰り返しを表すメタ文字
繰り返しを表すメタ文字を使うことで、特定のパターンが何回繰り返されるかを指定できます。
* (0回以上の繰り返し)
*
は直前の文字が0回以上繰り返されることにマッチします。
import re
text = "aaa, aa, a, "
pattern = r'a*'
result = re.findall(pattern, text)
print(result)
['aaa', 'aa', 'a', '']
+ (1回以上の繰り返し)
+
は直前の文字が1回以上繰り返されることにマッチします。
import re
text = "aaa, aa, a, "
pattern = r'a+'
result = re.findall(pattern, text)
print(result)
['aaa', 'aa', 'a']
? (0回または1回の繰り返し)
?
は直前の文字が0回または1回だけ出現することにマッチします。
import re
text = "abc, ac, a"
pattern = r'a?c'
result = re.findall(pattern, text)
print(result)
['ac', 'c', 'c']
{n,m} (n回からm回の繰り返し)
{n,m}
は直前の文字がn回からm回繰り返されることにマッチします。
import re
text = "aaa, aa, a, "
pattern = r'a{1,3}'
result = re.findall(pattern, text)
print(result)
['aaa', 'aa', 'a']
特殊シーケンス
特殊シーケンスは、特定の種類の文字にマッチするための短縮表現です。
\d (数字)
\d
は任意の数字(0-9)にマッチします。
import re
text = "私の年齢は30歳です。"
pattern = r'\d+'
result = re.findall(pattern, text)
print(result)
['30']
\w (単語文字)
\w
は任意の単語文字(アルファベット、数字、アンダースコア)にマッチします。
import re
text = "Python_3.8"
pattern = r'\w+'
result = re.findall(pattern, text)
print(result)
['Python_3', '8']
\s (空白文字)
\s
は任意の空白文字(スペース、タブ、改行など)にマッチします。
import re
text = "Hello, World!"
pattern = r'\s+'
result = re.split(pattern, text)
print(result)
['Hello,', 'World!']
\b (単語境界)
\b
は単語の境界にマッチします。
これにより、特定の単語が他の文字に囲まれていないかを確認できます。
import re
text = "私はPythonが好きです。"
pattern = r'\bPython\b'
match = re.search(pattern, text)
if match:
print("一致しました:", match.group())
一致しました: Python
実践例:正規表現で文字列を抽出する
正規表現を使うことで、特定のパターンに一致する文字列を簡単に抽出できます。
ここでは、実際の例を通じて、さまざまな文字列を抽出する方法を紹介します。
メールアドレスを抽出する
メールアドレスの形式に一致する文字列を抽出するための正規表現を使用します。
import re
text = "私のメールは example@example.com と test@test.co.jp です。"
pattern = r'\w+@\w+\.\w+'
result = re.findall(pattern, text)
print(result)
['example@example.com', 'test@test.co.jp']
この例では、メールアドレスの形式に一致する部分をすべて抽出しています。
電話番号を抽出する
日本の電話番号形式(例:090-1234-5678)に一致する文字列を抽出します。
import re
text = "連絡先は 090-1234-5678 と 03-1234-5678 です。"
pattern = r'\d{2,4}-\d{2,4}-\d{4}'
result = re.findall(pattern, text)
print(result)
['090-1234-5678', '03-1234-5678']
この例では、電話番号の形式に一致する部分を抽出しています。
URLを抽出する
ウェブサイトのURLを抽出するための正規表現を使用します。
import re
text = "訪問先は https://www.example.com と http://example.org です。"
pattern = r'https?://[^\s]+'
result = re.findall(pattern, text)
print(result)
['https://www.example.com', 'http://example.org']
この例では、HTTPまたはHTTPSで始まるURLを抽出しています。
日付形式を抽出する
日付の形式(例:YYYY/MM/DDやDD-MM-YYYY)に一致する文字列を抽出します。
import re
text = "重要な日付は 2023/10/01 と 01-10-2023 です。"
pattern = r'\d{4}/\d{1,2}/\d{1,2}|\d{1,2}-\d{1,2}-\d{4}'
result = re.findall(pattern, text)
print(result)
['2023/10/01', '01-10-2023']
この例では、異なる日付形式に一致する部分を抽出しています。
特定の単語やフレーズを抽出する
特定の単語やフレーズを抽出するための正規表現を使用します。
import re
text = "私はPythonとJavaが好きです。Pythonは楽しい言語です。"
pattern = r'Python'
result = re.findall(pattern, text)
print(result)
['Python', 'Python']
この例では、 Python
という単語が含まれる部分をすべて抽出しています。
正規表現のオプション
正規表現を使用する際には、さまざまなオプションを指定することで、マッチングの挙動を変更できます。
以下に代表的なオプションを紹介します。
大文字小文字を無視するre.IGNORECASE
re.IGNORECASE
オプションを使用すると、大文字と小文字を区別せずにマッチングを行うことができます。
import re
text = "Pythonは楽しい。pythonも楽しい。"
pattern = r'python'
result = re.findall(pattern, text, re.IGNORECASE)
print(result)
['Python', 'python']
この例では、re.IGNORECASE
を指定することで、 Python
と python
の両方に一致しています。
複数行に対応するre.MULTILINE
re.MULTILINE
オプションを使用すると、文字列内の各行の先頭や末尾に対して^
や$
がマッチするようになります。
import re
text = "Pythonは楽しい\nJavaも楽しい"
pattern = r'^Python'
match = re.search(pattern, text, re.MULTILINE)
if match:
print("一致しました:", match.group())
一致しました: Python
この例では、re.MULTILINE
を指定することで、複数行のテキストの先頭に Python
があるかどうかを確認しています。
ドットが改行にも一致するre.DOTALL
re.DOTALL
オプションを使用すると、.
が改行文字にも一致するようになります。
通常、.
は改行文字には一致しませんが、このオプションを指定することで、改行を含む任意の文字にマッチします。
import re
text = "Pythonは楽しい。\nJavaも楽しい。"
pattern = r'Python.*Java'
match = re.search(pattern, text, re.DOTALL)
if match:
print("一致しました:", match.group())
一致しました: Pythonは楽しい。
Java
この例では、re.MULTILINE
を指定することで、改行を含む Python
と Java
の間のすべての文字に一致しています。
コメントを許可するre.VERBOSE
re.VERBOSE
オプションを使用すると、正規表現内にコメントを含めることができ、可読性を向上させることができます。
このオプションを使用すると、空白やコメントが無視されます。
import re
pattern = r"""
\d{3} # 3桁の数字
- # ハイフン
\d{4} # 4桁の数字
- # ハイフン
\d{4} # 4桁の数字
"""
text = "電話番号は 090-1234-5678 です。"
match = re.search(pattern, text, re.VERBOSE)
if match:
print("一致しました:", match.group())
一致しました: 090-1234-5678
この例では、re.VERBOSE
を指定することで、正規表現にコメントを追加し、各部分の意味を明確にしています。
応用例:正規表現を使った高度な操作
正規表現は、基本的なパターンマッチングだけでなく、より高度な操作にも対応しています。
ここでは、グループ化や先読み、再帰的なパターンマッチングなどの応用例を紹介します。
グループ化とキャプチャ
グループ化を使用すると、特定の部分をまとめて扱うことができ、キャプチャを使ってその部分を抽出することができます。
グループは丸括弧()
で囲みます。
import re
text = "私の名前は山田太郎です。"
pattern = r'私の名前は(.*?)です。'
match = re.search(pattern, text)
if match:
print("キャプチャした名前:", match.group(1))
キャプチャした名前: 山田太郎
この例では、名前の部分をキャプチャして抽出しています。
非キャプチャグループ
非キャプチャグループは、(?:...)
の形式で指定し、マッチングには使用しますが、キャプチャは行いません。
これにより、不要なキャプチャを避けることができます。
import re
text = "apple, banana, cherry"
pattern = r'(?:apple|banana)'
result = re.findall(pattern, text)
print(result)
['apple', 'banana']
この例では、(?:...)
を使用して、キャプチャせずに apple
または banana
に一致する部分を抽出しています。
先読み・後読み
先読み(lookahead)と後読み(lookbehind)を使用すると、特定の条件を満たす場合にのみマッチングを行うことができます。
先読み
先読みは、(?=...)
の形式で指定し、後ろに特定のパターンが続く場合にマッチします。
import re
text = "Pythonは楽しい。Javaも楽しい。"
pattern = r'Python(?=は)'
match = re.search(pattern, text)
if match:
print("先読みで一致:", match.group())
先読みで一致: Python
この例では、 Python
の後に「は」が続く場合に一致しています。
後読み
後読みは、(?<=...)
の形式で指定し、前に特定のパターンがある場合にマッチします。
import re
text = "私の好きな言語はPythonです。"
pattern = r'(?<=好きな言語は)Python'
match = re.search(pattern, text)
if match:
print("後読みで一致:", match.group())
後読みで一致: Python
この例では、「好きな言語は」の後に Python
が続く場合に一致しています。
<...>
の部分をグループ化し、対応する閉じタグを確認しています。
よくある質問
まとめ
この記事では、Pythonにおける正規表現の基本的な使い方から、応用的なテクニックまで幅広く解説しました。
正規表現を活用することで、文字列のパターンマッチングや抽出、置換が効率的に行えるようになります。
これを機に、実際のプログラミングに正規表現を取り入れて、より複雑な文字列処理に挑戦してみてください。