文字列の一部を別の文字列に置換するときには str.replace( )
を使います.複雑な条件で検索した文字列を別の文字列に置換するためには,正規表現による re.sub( )
を利用することになります.
文字列オブジェクトの replace( )
を使うことで文字列の一部を別の文字に置き換えることができます.例えば,次のような百人一首のある歌文字列を準備します.
msg = '秋の田の かりほの庵の 苫をあらみ わが衣手は 露にぬれつつ'
msg
'秋の田の かりほの庵の 苫をあらみ わが衣手は 露にぬれつつ'
この文字列には半角空白が含まれています.この半角空白を「/」に置き換えるには次のように入力します.
msg.replace(' ', '/')
'秋の田の/かりほの庵の/苫をあらみ/わが衣手は/露にぬれつつ'
上の例では文字列の中にある全ての半角空白が置換されました.次のように置換の最大回数を指定することも可能です.
msg.replace(' ', '/', 2)
'秋の田の/かりほの庵の/苫をあらみ わが衣手は 露にぬれつつ'
置き換える文字を空文字にすると半角空白を削除することができます.
msg.replace(' ', '')
'秋の田のかりほの庵の苫をあらみわが衣手は露にぬれつつ'
複数の文字列をそれぞれ別の文字列に置き換えたい場合は .replace()
を繰り返して記述します.例えば半角空白を削除し,さらに「の」を「ノ」に置き換える場合は次のように記述します.
msg.replace(' ', '').replace('の', 'ノ')
'秋ノ田ノかりほノ庵ノ苫をあらみわが衣手は露にぬれつつ'
この .replace()
は1文字だけでなく文字列を置換することができるので,「日本」を「兵庫県神戸市」に置き換えることも可能です.
msg = '彼は日本に生まれ日本で育ちました'
msg.replace('日本', '兵庫県神戸市')
'彼は兵庫県神戸市に生まれ兵庫県神戸市で育ちました'
複雑な条件で検索した文字列を別の文字列に置換するためには,正規表現を利用することになります.ここでは詳しく説明しませんが,正規表現では行の先頭やn文字以上の繰り返しなど様々な検索が可能です.正規表現を利用するためには(通常はプログラムの先頭で) re
ライブラリをインポートします.
import re
再び百人一首のある歌の文字列を準備しますが,今度は半角空白だけでなく,タブ文字と全角空白も含まれています.
# \t はタブ文字です
msg = '秋の田の かりほの庵の 苫をあらみ\tわが衣手は 露にぬれつつ'
msg
'秋の田の かりほの庵の 苫をあらみ\tわが衣手は\u3000露にぬれつつ'
これを print( )
で表示すると次のような結果になります.
print(msg)
秋の田の かりほの庵の 苫をあらみ わが衣手は 露にぬれつつ
正規表現を使って複数の条件で検索したい場合には,[ ]
の中に複数の検索文字を列挙します.例えば「タブ文字 (\t)」または「半角空白」または「全角空白」を検索して,それを「/」に置換します.
re.sub('[\t ]', '/', msg)
'秋の田の/かりほの庵の/苫をあらみ/わが衣手は/露にぬれつつ'
文字コード表の範囲を指定してその範囲に含まれる文字を別の文字に置き換えることもできます.例えば「0」から「9」の範囲を [0-9]
のように指定して数値を「x」に置き換えることができます.次の例では学籍番号を隠しています.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[0-9]', 'x', msg))
6121991_Eto, 6121992_Sato, 6121993_Kato xxxxxxx_Eto, xxxxxxx_Sato, xxxxxxx_Kato
学籍番号の下3桁だけを隠したい場合は,アンダースコア ( _ ) とその直前にある3桁の数字を検索して「xxx_」に置換すれば良いので,次のように記述します.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[0-9][0-9][0-9]_', 'xxx_', msg))
6121991_Eto, 6121992_Sato, 6121993_Kato 6121xxx_Eto, 6121xxx_Sato, 6121xxx_Kato
同じパターンの繰り返しを検索したい場合はその回数 n をパターンの直後に {n}
で指定します.したがって,次のように書いても同じ結果が得られます.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[0-9]{3}_', 'xxx_', msg))
6121991_Eto, 6121992_Sato, 6121993_Kato 6121xxx_Eto, 6121xxx_Sato, 6121xxx_Kato
アルファベットの大文字をすべて隠したい場合は [A-Z]
のように指定します.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[A-Z]', '?', msg))
6121991_Eto, 6121992_Sato, 6121993_Kato 6121991_?to, 6121992_?ato, 6121993_?ato
大文字とそれに続く小文字1文字も隠したい場合は次のように指定します.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[A-Z][a-z]', '??', msg))
6121991_Eto, 6121992_Sato, 6121993_Kato 6121991_??o, 6121992_??to, 6121993_??to
アルファベットをすべて隠したい場合は [A-Za-z]
と指定します.これはつまり「A」から「Z」または「a」から「z」を意味します.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[A-Za-z]', '?', msg))
6121991_Eto, 6121992_Sato, 6121993_Kato 6121991_???, 6121992_????, 6121993_????
なお,文字コード表を確認すると「Z」と「a」の間に,「_」などの記号が存在するため,[A-z]
のように指定すると,アンダースコアも置換されてしまうことになります.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[A-z]', '?', msg))
6121991_Eto, 6121992_Sato, 6121993_Kato 6121991????, 6121992?????, 6121993?????
最後に,学籍番号を「x」に,名前を「?」に置換してみます.このとき,処理の順番が異なると思わぬ結果になる(すべてが「?」になる)理由も考えてみてください.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
msg = re.sub('[A-Za-z]', '?', msg)
print(msg)
msg = re.sub('[0-9]', 'x', msg)
print(msg)
6121991_Eto, 6121992_Sato, 6121993_Kato 6121991_???, 6121992_????, 6121993_???? xxxxxxx_???, xxxxxxx_????, xxxxxxx_????
同じ処理を一気に行うことも可能です.
msg = '6121991_Eto, 6121992_Sato, 6121993_Kato'
print(msg)
print(re.sub('[0-9]', 'x', re.sub('[A-Za-z]', '?', msg)))
6121991_Eto, 6121992_Sato, 6121993_Kato xxxxxxx_???, xxxxxxx_????, xxxxxxx_????