Edited at

Pythonで個人的によく使う正規表現モジュールの機能

More than 1 year has passed since last update.

ちょくちょく忘れるのですが,公式ドキュメントは文量多すぎて,毎回調べるのが辛くなってきたので,備忘録的なものを.必要に応じて付け足していく予定.

import re

ちなみに,from sympy import * とすると,実部を返すre関数と被るので注意.


マッチオブジェクト

マッチした部分を取り出すには……

filename = 'Back_in_the_U.S.S.R.m4a'

m = re.match(r'([\w\.-]+?)\.(\w+)$', filename)
print(m.group(0)) #マッチした箇所全体(m.group()と等価?)
print(m.group(1)) #1番目のグループ
print(m.group(2)) #2番目のグループ
print(m.groups()) #グループ全体をタプルで


out

Back_in_the_U.S.S.R.m4a

Back_in_the_U.S.S.R
m4a
('Back_in_the_U.S.S.R', 'm4a')

(?P<groupname> ) でグループに名前をつけて,キーワードからアクセス.

filename = 'Back_in_the_U.S.S.R.m4a'

m = re.match(r'(?P<basename>[\w\.]+?)\.(?P<ext>\w+)$', filename)
print(m.group('basename')) #(?P<basename> )にマッチした文字列
print(m.group('ext')) #(?P<ext> )にマッチした文字列
print(m.groupdict()) #名前付きのグループを辞書で


out

Back_in_the_U.S.S.R

m4a
{'basename': 'Back_in_the_U.S.S.R', 'ext': 'm4a'}


マッチした文字列を置換に利用

例えば $\LaTeX$ の \ruby{帰謬法}{きびゅうほう}<ruby>帰謬法<rt>きびゅうほう</rt></ruby> に置換するには……

print(re.sub(r'\\ruby\{(\w+)\}\{(\w+)\}',

r'<ruby>\1<rt>\2</rt></ruby>',
r'\ruby{帰謬法}{きびゅうほう}'))


out

<ruby>帰謬法<rt>きびゅうほう</rt></ruby>


(?P<groupname> ) で名前を付けたグループを使う参照する場合は \g<groupname> とします.

print(re.sub(r'\\ruby\{(?P<rb>\w+)\}\{(?P<rt>\w+)\}',

r'<ruby>\g<rb><rt>\g<rt></rt></ruby>',
r'\ruby{帰謬法}{きびゅうほう}'))


out

<ruby>帰謬法<rt>きびゅうほう</rt></ruby>


htmlのタグとややこしいですが,同様の結果が返ってきました.


マッチした部分すべてをリストに

HTMLのem要素またはstrong要素の内容を全て取り出すには……

src = r'<em>選択公理</em>を仮定すると,任意の集合に<strong>整列順序を入れられる</strong>.'

re.findall(r'<(em|strong)>(.*?)</\1>', src)


out

[('em', '選択公理'), ('strong', '整列順序を入れられる')]



マッチした箇所を関数に渡して置換

テキスト内のなんとかcmをなんとかmに直すには……

def cm2m(m): #マッチオブジェクトを引数とする関数を用意

value = m.group(1)
return str(float(value)/100) + 'm'
print(re.sub(r'(\d+)cm', cm2m, '271cm + 314cm は 585cm です.'))


out

2.71m + 3.14m は 5.85m です.


わざわざ関数を定義するまでもない単純な処理の場合はlambdaがいいのかなと.

print(re.sub(r'(\d+)cm', lambda m: str(float(m.group(1))/100) + 'm', '271cm + 314cm は 585cm です.'))


out

2.71m + 3.14m は 5.85m です.



ネストした括弧

再帰を用います.しかし,標準のreにはない機能なので,regexを.インストールされてなければ pip install regex などで.以下は $\LaTeX$ の \frac{ }{ } にマッチします(多分).

import regex

pattern_frac = r'\\frac(?<rec>\{(?:[^{}]+|(?&rec))*\}){2}'
m = regex.search(pattern_frac, r'1 + \frac{\int_{a}^{b} f(x)\,dx }{\sum_{k=1}^{n}a_{k}}')
print(m.group())


out

\frac{\int_{a}^{b} f(x)\,dx }{\sum_{k=1}^{n}a_{k}}