正規表現を実際の処理へ使うための練習問題です。各問題では、まずパターンを自分で考えてからコードを実行し、入力例を変更して結果を確認してください。
練習1:基本的な文字列マッチング#
目標#
123-456-7890または10桁の数字として書かれた電話番号を取り出す。testで始まる単語を取り出す。
import re
text = """
連絡先A: 123-456-7890
連絡先B: 9876543210
テストデータ: test1, test2, testing
"""
phone_pattern = r'\d{3}-\d{3}-\d{4}|\d{10}'
phones = re.findall(phone_pattern, text)
print("電話番号:", phones)
test_pattern = r'\btest\w*\b'
test_words = re.findall(test_pattern, text)
print("testで始まる単語:", test_words)練習2:ファイル名の一括変更#
目標#
指定したディレクトリ内からtest_で始まるファイルを見つけ、接頭辞を削除して名前を変更します。
import os
import re
folder_path = r'/path/to/folder'
pattern = re.compile(r'^test_(.+)$')
for root, dirs, files in os.walk(folder_path):
for filename in files:
match = pattern.match(filename)
if not match:
continue
new_name = match.group(1)
old_path = os.path.join(root, filename)
new_path = os.path.join(root, new_name)
os.rename(old_path, new_path)
print(f"変更: {filename} -> {new_name}")実際に名前を変更する前に、print(old_path, new_path)だけにして対象を確認すると安全です。同名ファイルがすでにある場合の扱いも、事前に決めておきます。
練習3:HTMLタグと空白の除去#
目標#
- HTMLタグを取り除く。
- 連続する空白文字を1つの半角スペースへ置き換える。
import re
text = """
<html>
<body>
<h1>テストページ</h1>
<p>これは段落です。</p>
<p> 余分な空白があります。 </p>
</body>
</html>
"""
without_tags = re.sub(r'<[^>]+>', '', text)
clean_text = re.sub(r'\s+', ' ', without_tags).strip()
print(clean_text)HTMLを本格的に解析する場合、正規表現ではなくHTMLパーサーを使ってください。ここでは単純な練習としてタグを除去しています。
練習4:メールアドレスとURLの形式確認#
目標#
入力が簡単なメールアドレスまたはURLの形式に合うか確認します。
import re
email = input("メールアドレスを入力してください: ")
email_pattern = r'^[A-Za-z0-9_.+-]+@[A-Za-z0-9-]+\.[A-Za-z0-9.-]+$'
print(bool(re.fullmatch(email_pattern, email)))
url = input("URLを入力してください: ")
url_pattern = r'^https?://[A-Za-z0-9.-]+\.[A-Za-z]{2,}(/.*)?$'
print(bool(re.fullmatch(url_pattern, url)))実際のメールアドレスやURLの仕様はこのパターンより複雑です。ユーザー入力を厳密に検証する場合は、専用ライブラリやフレームワークのバリデーターを使います。
練習5:ログからIPv4アドレスを抽出する#
import re
log_data = """
192.168.0.1 - - [24/Nov/2024:14:15:22] "GET /index.html HTTP/1.1" 200
10.0.0.5 - - [24/Nov/2024:14:16:00] "POST /form.html HTTP/1.1" 404
Invalid log entry 123.456.789.0
"""
octet = r'(?:25[0-5]|2[0-4]\d|[01]?\d\d?)'
ip_pattern = rf'(?<![\d.])(?:{octet}\.){{3}}{octet}(?![\d.])'
ips = re.findall(ip_pattern, log_data)
print("IPv4アドレス:", ips)IPv4の各オクテットを0から255に制限するため、単に\d{1,3}と書くより長いパターンになります。
練習6:複雑なファイル名を変換する#
次の形式のファイル名を考えます。
コース1_章2_説明_1700000000.txtコース番号と章番号を取り出し、コース1-章2.txtへ変換します。
import os
import re
folder_path = r'/path/to/folder'
pattern = re.compile(r'^(コース\d+)_(章\d+)_.+?_(\d+)\.(.+)$')
for root, dirs, files in os.walk(folder_path):
for filename in files:
match = pattern.match(filename)
if not match:
continue
course, chapter, _, extension = match.groups()
new_name = f'{course}-{chapter}.{extension}'
os.rename(os.path.join(root, filename), os.path.join(root, new_name))
print(f"変更: {filename} -> {new_name}")練習7:ユーザー入力からパターンを作る#
ユーザーが入力したキーワードのいずれかを含む文を探します。入力をそのまま正規表現へ連結すると、+や[などが特別な意味を持つため、re.escape()でエスケープします。
import re
text = """
今日は正規表現を勉強しました。
Pythonのプログラミングは便利です。
人工知能についても学びたいです。
"""
keywords = input("キーワードを空白区切りで入力してください: ").split()
keyword_pattern = '|'.join(map(re.escape, keywords))
if keyword_pattern:
sentence_pattern = rf'[^。!?]*?(?:{keyword_pattern})[^。!?]*[。!?]'
sentences = re.findall(sentence_pattern, text, re.IGNORECASE)
print("マッチした文:", sentences)発展させるポイント#
- 大文字・小文字を区別するかを
re.IGNORECASEで切り替える。 - 行単位の処理では
re.MULTILINEを試す。 - ログ解析では、名前付きキャプチャグループを使って日付やステータスを取り出す。
- ファイルを変更するコードは、最初に対象だけを表示してから実行する。
- 複雑なHTML、JSON、プログラミング言語の構文は、専用パーサーを優先する。
まとめ#
これらの練習を通じて、正規表現のマッチング、置換、キャプチャ、ファイル操作、入力検証への応用を確認できます。パターンを少しずつ変更し、境界値や不正な入力も試すと、実際の処理で使える理解が身につきます。


