【Pythonチュートリアル】正規表現オブジェクト(re)を使って、Webスクレイピングや自然言語処理のタスクを自動化する方法
reモジュールの基本
まず、re
モジュールをインポートする必要があります。
import re
正規表現パターンの記述
正規表現パターンは、特殊な記号を使って記述されます。主な記号は以下の通りです。
()
: グループ化を表します。[]
: 指定した文字のいずれかに一致することを表します。$
: 行の末尾を表します。^
: 行の先頭を表します。?
: 直前のパターンを0回または1回繰り返すことを表します。+
: 直前のパターンを1回以上繰り返すことを表します。*
: 直前のパターンを0回以上繰り返すことを表します。.
: 任意の1文字を表します。
例:
abc?
: "abc" または "ab" に一致します。ab*
: "a" の後に "b" が0回以上続く文字列に一致します。[abc]
: 文字 "a"、"b"、または "c" のいずれかに一致します。abc
: 文字列 "abc" に一致します。
正規表現関数の利用
re
モジュールには、以下の主要な関数が用意されています。
sub()
: パターンに一致する部分を置換文字列で置換します。findall()
: パターンに一致するすべての部分文字列をリストとして返します。match()
: 文字列の先頭から一致するパターンを検索し、Match
オブジェクトを返します。search()
: 最初に一致するパターンを検索し、Match
オブジェクトを返します。
例:
# 文字列 "Hello, world!" から "world" を検索
match = re.search(r"world", "Hello, world!")
if match:
print(match.group()) # "world" を出力
# 文字列 "Python programming" から "n" をすべて "N" に置換
new_text = re.sub(r"n", "N", "Python programming")
print(new_text) # "PythoN programmimg" を出力
Matchオブジェクト
search()
, match()
, findall()
関数は、一致情報を含む Match
オブジェクトを返します。このオブジェクトには、以下のメソッドが用意されています。
span()
: 一致した部分文字列の開始位置と終了位置をタプルで返します。end()
: 一致した部分文字列の終了位置を取得します。start()
: 一致した部分文字列の開始位置を取得します。group(n)
: 指定されたグループ番号の部分文字列を取得します。group()
: 一致した部分文字列全体を取得します。
例:
# 文字列 "Python programming" から "n" を検索
match = re.search(r"n", "Python programming")
# 一致した部分文字列全体を取得
print(match.group()) # "n" を出力
# 指定されたグループ番号の部分文字列を取得
print(match.group(1)) # 空文字列を出力 (グループ番号1は定義されていない)
# 一致した部分文字列の開始位置を取得
print(match.start()) # 6 を出力
# 一致した部分文字列の終了位置を取得
print(match.end()) # 7 を出力
# 一致した部分文字列の開始位置と終了位置をタプルで取得
print(match.span()) # (6, 7) を出力
- 正規表現は複雑になりがちなので、可読性を高めるために名前付きグループやコメントなどを活用しましょう。
正規表現オブジェクト(re)は、Pythonにおけるテキスト処理において非常に強力なツールです。基本的な概念を理解することで、様々なテキスト処理タスクを効率的にこなすことができます。
以下は、re
モジュールを活用したテキスト処理の応用例です。
- HTMLタグを除去してテキスト
- 特定の形式のメールアドレスや電話番号を抽出する
特定の形式のメールアドレスを抽出する
import re
text = """
この度は、大変お世話になっております。
株式会社〇〇 〇〇様
〇〇 〇〇 部 〇〇 〇〇様
本文
敬具
〇〇株式会社
〇〇 〇〇
"""
# 正規表現パターン
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
# パターンに一致する部分文字列をすべて抽出
emails = re.findall(email_pattern, text)
# 抽出結果の表示
for email in emails:
print(email)
出力
この度は、大変お世話になっております。
株式会社〇〇 〇〇様
〇〇 〇〇 部 〇〇 〇〇様
本文
敬具
〇〇株式会社
〇〇 〇〇
このコードは、re
モジュールを使って、HTMLタグをすべて除去して、テキストコンテンツのみを取得します。
import re
html_text = """
<!DOCTYPE html>
<html>
<head>
<title>サンプルページ</title>
</head>
<body>
<h1>本文</h1>
<p>これはサンプルの段落です。</p>
</body>
</html>
"""
# HTMLタグを除去する正規表現パターン
tag_pattern = r"<[^>]+>"
# パターンに一致しない部分文字列をすべて結合して取得
text_content = re.sub(tag_pattern, "", html_text)
# 取得結果の表示
print(text_content)
出力
本文
これはサンプルの段落です。
上記はほんの一例です。re
モジュールを活用することで、様々なテキスト処理タスクを実現することができます。
- より複雑な処理を行う場合は、正規表現の高度な機能を活用する必要があります。
- 上記のコードはあくまで基本的な例であり、状況に合わせて調整する必要があります。
文字列メソッド
Pythonの組み込み文字列メソッドの中には、簡単なパターンマッチングに十分な機能を持つものがあります。
str.replace()
: 文字列の一部を別の文字列に置換します。str.endswith()
: 文字列が特定の文字列 (サフィックス) で終わるかどうかを判定します。str.startswith()
: 文字列が特定の文字列 (プレフィックス) で始まるかどうかを判定します。str.count()
: 特定の文字列 (サブストリング) が出現する回数をカウントします。str.find()
: 特定の文字列 (サブストリング) が最初に一致する位置を検索します。
例
text = "Pythonプログラミングは楽しい!"
# "Python" が最初に一致する位置を検索
position = text.find("Python")
print(position) # 0 を出力
# "g" が出現する回数をカウント
count = text.count("g")
print(count) # 2 を出力
# 文字列が "Python" で始まるかどうかを判定
is_start_with_python = text.startswith("Python")
print(is_start_with_python) # True を出力
# 文字列が "!" で終わるかどうかを判定
is_end_with_exclamation = text.endswith("!")
print(is_end_with_exclamation) # True を出力
# "プログラミング" を "コーディング" に置換
new_text = text.replace("プログラミング", "コーディング")
print(new_text) # "Pythonコーディングは楽しい!" を出力
利点
- コードが簡潔になる
- シンプルで分かりやすい
欠点
re
モジュールほど機能が豊富ではない- 複雑なパターンマッチングには不向き
fnmatch モジュール
fnmatch
モジュールは、Unix シェルのファイル名マッチングパターンに似たパターンを使用して、文字列をマッチングすることができます。
例
import fnmatch
text = "hello.txt"
# "hello*.txt" に一致するかどうかを判定
is_match = fnmatch(text, "hello*.txt")
print(is_match) # True を出力
# "*.py" に一致するかどうかを判定
is_match = fnmatch(text, "*.py")
print(is_match) # False を出力
利点
- シンプルなパターンマッチングに適している
- Unix シェルのパターンと互換性がある
欠点
re
モジュールほど機能が豊富ではない- 複雑なパターンマッチングには不向き
上記以外にも、以下のようなライブラリが提供されています。
これらのライブラリは、それぞれ異なる機能と強みを持っているので、具体的なニーズに合わせて選択する必要があります。
re
モジュールは、汎用性が高く、複雑なパターンマッチングにも対応できるため、テキスト処理におけるパターンマッチングの第一候補としておすすめです。
しかし、シンプルなパターンマッチングであれば、文字列メソッドやfnmatch
モジュールの方が軽量で効率的な場合があります。