It seems like every time I want to use string.maketrans and str.translate, I have to stop for a minute and think really hard about how to accomplish what I want to do. Eventually, I wrote this little wrapper class to ease my pain.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
import string class Translator: allchars = string.maketrans('','') def __init__(self, frm='', to='', delete='', keep=None): if len(to) == 1: to = to * len(frm) self.trans = string.maketrans(frm, to) if keep is None: self.delete = delete else: self.delete = self.allchars.translate(self.allchars, keep.translate(self.allchars, delete)) def __call__(self, s): return s.translate(self.trans, self.delete)
This class handles the three most common cases where I find myself having to stop and think about how to use translate:
1) Keeping only a given set of characters.
>>> trans = Translator(keep=string.digits) >>> trans('Chris Perkins : 224-7992') '2247992'
2) Deleting a given set of characters.
>>> trans = Translator(delete=string.digits) >>> trans('Chris Perkins : 224-7992') 'Chris Perkins : -'
3) Replacing a set of characters with a single character.
>>> trans = Translator(string.digits, '#') >>> trans('Chris Perkins : 224-7992') 'Chris Perkins : ###-####'
This last one is admittedly a bit of a special case, but it is something I seem to need to do once in a while.
Note that the delete parameter trumps the keep parameter if they overlap:
>>> trans = Translator(delete='abcd', keep='cdef') >>> trans('abcdef') 'ef' This is an arbitrary design choice - makes as much sense as anything, I suppose.
See also: 1) http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/101521 for an excellent explanation of maketrans and translate. 2) http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/59857 for an equivalent to Translate(keep=whatever).