#1.やりたいこと
Pythonの正規表現置換でマッチした文字列を置換に利用したい。
毎回忘れるのでメモ
#2. 例えば?
英文解析で、こんなリストがあったとします。
sentence = ['During', 'this', 'time', ',', 'many', 'chatterbots', 'were', 'written', 'including',
'PARRY', ',', 'Racter', ',', 'and', 'Jabberwacky', '.']
これを(1文全体の)文字列にしたいな〜と思った時にまず考えつくのはjoinですよね。
' '.join(sentence)
#During this time , many chatterbots were written including PARRY , Racter , and Jabberwacky .
はい…もう察しだと思われますが、.
とか,
とかの 前に半角スペース が入っています。
困りましたねぇ
じゃあどうするか…そうです。正規表現で置換しちゃえ!
でも,
とか.
とかどうやって置換しようか。
#3. マッチした文字列を置換先で再利用
とりあえずやってみましょう。
import re
bad = ' '.join(sentence)
fixed = re.sub(r' ([,.])', r'\1', bad)
# r' [,.]' : 半角スペース+「,」「.」のどれか
print(fixed)
During this time, many chatterbots were written including PARRY, Racter, and Jabberwacky.
完成!
#4.ちょっとだけ解説
re.sub
を使う時、
第一引数のパターン文字列の中で、再利用したい部分を ()
で囲み
第二引数の文字列の置換したい部分に何番目の ()
を使いたいか「:1番目なら \1
」を指定します。
これを踏まえて、幾つか例を書いてみます。
bad = 'including PARRY , Racter , and Jabberwacky .'
# さっきのやつ
re.sub(r' ([,.])', r'\1', bad)
Out[4]: 'including PARRY, Racter, and Jabberwacky.'
# 「(」の場所が違う
re.sub(r'( [,.])', r'\1', bad)
Out[5]: 'including PARRY , Racter , and Jabberwacky .' # == bad
# 「()」でスペースを囲ってみる
re.sub(r'( )([,.])', r'\1', bad)
Out[6]: 'including PARRY Racter and Jabberwacky '
# 使う番目を変更
re.sub(r'( )([,.])', r'\2', bad)
Out[7]: 'including PARRY, Racter, and Jabberwacky.'
# 繋げて使ってみる
re.sub(r'( )([,.])', r'\1\2', bad)
Out[8]: 'including PARRY , Racter , and Jabberwacky .' # == bad
# 逆はどうか
re.sub(r'( )([,.])', r'\2\1', bad)
Out[9]: 'including PARRY, Racter, and Jabberwacky. ' # != bad
# 遊んでみる
re.sub(r'( )([,.])', r'\1ほげ\2', bad)
Out[12]: 'including PARRY ほげ, Racter ほげ, and Jabberwacky ほげ.'
補足
必ず '\num'
の前にはr
をつけてください。追記有り
良い例r'\1'
悪い例'\1'
##追記(2017/01/19)
追加でバックスラッシュ\
をつければr
を付けなくても動くそうです。
コメントで教えてくださったshiracamusさんありがとうございます。
'\num'
の場合はr
を付ける必要がありますが、'\\num'
にすればr
を付けなくていいですよ。
r は raw(生=なま、未加工) の意味で、バックスラッシュをエスケープ文字として処理しない生(未加工)の文字列です。
>>> import re
>>> bad = 'including PARRY , Racter , and Jabberwacky .'
>>> re.sub(' ([,.])', '\\1', bad)
'including PARRY, Racter, and Jabberwacky.'
他にもおかしい点ありましたら、是非コメントにて教えて頂ける助かります。