この記事では、Pythonの正規表現で非常に強力なワイルドカード
文字であるドット.
、それを用いたドットスター(.*)
パターン、そしてマッチした文字列を置換するsub()
メソッドについて解説します。
ドット.
:任意の1文字にマッチ(ワイルドカード)
正規表現において、ドット.
は改行文字\n
以外の任意の1文字にマッチする特殊なワイルドカードです。
例えば、r's.t'
というパターンは、「s」で始まり「t」で終わる、間の1文字が何であれ3文字の文字列(”sat”, “set”, “s t”など)にマッチします。
import re
# パターン: 任意の1文字の後に'ot'が続く
pattern = re.compile(r'.ot')
text = "A hot pot got too hot for the cot."
results = pattern.findall(text)
print(results)
実行結果:
['hot', 'pot', 'got', 'hot', 'cot']
ドットスター.*
:任意の文字列にマッチ
ドット.
とアスタリスク*
(0回以上の繰り返し)を組み合わせた.*
というパターンは、改行文字\n
を含まない任意の文字列にマッチします。これは非常に多用されるパターンです。
デフォルトでは、.*
は**貪欲(greedy)**に動作し、可能な限り最長の文字列にマッチします。
import re
# パターン: `Key:`と`Value:`の間にある任意の文字列をグループ化
pattern = re.compile(r'Key: (.*) Value: (.*)')
text = "Key: UserID Value: 12345"
match = pattern.search(text)
print(f"グループ1: {match.group(1)}") # 出力: UserID
print(f"グループ2: {match.group(2)}") # 出力: 12345
非貪欲(non-greedy)モードで最短のマッチを得たい場合は、.*?
のように?
を追加します。
# 貪欲マッチ
greedy_pattern = re.compile(r'<.*>')
text = "<tag1> some text </tag1>"
print(f"貪欲な結果: {greedy_pattern.search(text).group()}") # 出力: <tag1> some text </tag1>
# 非貪欲マッチ
nongreedy_pattern = re.compile(r'<.*?>')
print(f"非貪欲な結果: {nongreedy_pattern.search(text).group()}") # 出力: <tag1>
re.DOTALL
:改行を含むすべての文字にマッチさせる
前述の通り、ドット.
はデフォルトでは改行文字\n
にマッチしません。もし改行も含めてすべての文字にマッチさせたい場合は、re.compile()
の第2引数にre.DOTALL
を指定します。
import re
multiline_text = "First line.\nSecond line.\nThird line."
# re.DOTALLなし(改行でマッチが止まる)
no_dotall_pattern = re.compile(r'.*')
print(no_dotall_pattern.search(multiline_text).group()) # 出力: First line.
# re.DOTALLあり(改行も含めてすべてにマッチ)
dotall_pattern = re.compile(r'.*', re.DOTALL)
print(dotall_pattern.search(multiline_text).group()) # 出力: First line.\nSecond line.\nThird line.
sub()
メソッドによる文字列の置換
sub()
メソッドは、正規表現にマッチした部分を、指定した文字列で置換(find and replace)します。
例えば、Agent
で始まる単語を見つけ、その名前の部分を隠す、といった処理が可能です。置換文字列の中では、\1
, \2
のように、パターン内のグループを参照(バックリファレンス
)できます。
import re
text = "Agent Alice contacted Agent Bob about the mission."
# パターン: "Agent "の後の英数字の単語をグループ1としてキャプチャ
agent_pattern = re.compile(r'Agent (\w+)')
# マッチした部分を置換。`\1`はグループ1の内容を参照する
new_text = agent_pattern.sub(r'Agent \1****', text)
print(new_text)
実行結果:
Agent Alice**** contacted Agent Bob**** about the mission.
まとめ
正規表現のドット.
は任意の1文字を表す強力なワイルドカードです。.*
と組み合わせることで柔軟な文字列マッチングが可能になり、re.DOTALL
オプションでその範囲を改行文字にも広げることができます。また、sub()
メソッドは、パターンに一致した部分を置換する機能を提供し、テキストの編集やマスキングに役立ちます。