Python レシピ追加、文字列の一部を特定の文字で埋める
Ruby レシピブック 第2版 には Password: PythonRecipe のようなテキストを Password: ************ に置き換える例が載っていたので、これに則ったコードを。
# coding: utf-8 import re def hide(pattern, string, rep=u'*', hide_group=1): u"""正規表現 pattern の hide_group 部分を rep に置き換える >>> hide(u'Password: (.*)', u'Password: PythonRecipe') u'Password: ************' >>> hide(u'ham', u'spam ham eggs', hide_group=0) u'spam *** eggs' >>> hide(ur'(?P<year>\d+)-(?P<month>\d{1,2})-(?P<day>\d{1,2})', ... u'2009-12-09', hide_group='month') u'2009-**-09' """ r = re.compile(pattern) m = r.search(string) if not m: raise ValueError(u'No match') start, end = m.span(hide_group) return u''.join([ string[:start], (end - start) * rep, string[end:]]) def hide_password(string): u"""パスワード部分を隠す >>> hide_password(u'Password: PythonRecipe') u'Password: ************' """ return hide(u'Password: (.*)', string)
hide 関数は汎用性を少しだけ意識している。
>>> hide(ur'(?P<year>\d+)-(?P<month>\d+)', u'2009-12', hide_group='month') u'2009-**' >>> hide(ur'(?P<year>\d+)-(?P<month>\d+)', u'2009-12', hide_group=0) u'*******'
hide_group=['year', 'month'] のようにグループの複数指定をできるようにとか、グループにマッチ「しなかった」部分を置き換えたい、などなど、要求が増えるともう少し手を加えないといけなかったり。後で書く、かも。
re.compile をはじめとした re の関数は pattern 文字列の代わりに正規表現オブジェクトを渡しても動作するので、
>>> import re >>> r = re.compile(u'spam') >>> r is re.compile(r) # すでに正規表現オブジェクトならオウム返し True
hide 関数も正規表現オブジェクトを受け取ることができる。
>>> import re >>> r = re.compile(u'(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+)') >>> hide(r, u'2009-12-09', hide_group='day') u'2009-12-**'