毎日ちょっとPython ~ 17日目 ~
時間を決めてから3日連続の投稿よ。毎日続けるには時間を決めるのは有効だな。
大文字・小文字を無視したマッチ
基本、正規表現は大文字小文字を区別します。大文字小文字を無視ししたい場合は、compileのときに re.I オプションを渡します。
>>> robocop = re.compile(r'robocop',re.I)
>>> robocop.search('RoboCop is part man, pat machine,all cop.').group()
'RoboCop'
>>> robocop.search('ROBOCOP protects the innocent.').group()
'ROBOCOP'
>>> robocop.search('Al, why does your programming book talk about robocop so much?').group()
'robocop'
sub() メソッドを用いて文字列を置換する
正規表現は置換するのにも使えます。Regexオブジェクトのsub()メソッドは引数を二つ取ります。
第1引数 - 置き換える文字列
第2引数 - 検索置換対象の文字列
>>> names_regex = re.compile(r'Agent \w+')
>>> names_regex.sub('CENSORED','Agent Alice gave the secret documents to Agent Bob.')
'CENSORED gave the secret documents to CENSORED.'
Pythonって引数渡すとき基本、逆だよな。うん。
マッチした文字列を置き換えの一部として使うことができます。sub()の第一引数に\1,\2,\3のように、グループの番号を使って記述する。
名前を検閲し、頭文字だけで表示したい場合。(\w)\w*という正規表現を用いて sub() の第一引数に \1***** を渡します。
>>> agent_names_regex = re.compile(r'Agent (\w)\w*')
>>> agent_names_regex.sub(r'\1****','Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')
'A**** told C**** that E**** knew B**** was a double agent.'
※レシピブックみたいで面白い。
複雑な正規表現を管理する
正規表現は、マッチしようとするテキストのパターンが単純なうちはよいのですが、複雑になってくると長くてややこしい記述になります。正規表現の文字列中の空白文字やコメントを無視するようにre.compile()関数に指定すれば、この問題を緩和できます。この冗長モードを指定するには、re.VERBOSEを渡します。
phone_regex = re.compile(r'''
((\d{3}|\(\d{3}\))? # 3桁の市外局番(()がついてよい)
(\s|-|\.)? # 区切り(スペースかハイフンかドット)
\d{3} # 3桁の市内局番
(\s|-|\.) # 区切り
\d{4} # 4桁の番号
(\s*(ext|x|ext.)\s*\d{2,5})? # 2~5の内線番号
)''', re.VERBOSE)
最後に
正規表現パートが長い。