Cookbook - multireplace
Paul D. Lusk
plusk at radford.edu
Thu Sep 19 20:45:10 EDT 2002
This is more an exercise in sub-classing a dict than a speed optimization.
It may not even be a speed optimization, since I didn't time it.
# Original algorithm by Xavier Defrang.
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
# and modified by alane at sourceforge.net
# This implementation by plusk at radford.edu
import re
class NotImplemented(Exception):
pass
class textsub(dict):
__slots__ = ('pat','regex','flags')
def __init__(self, *ds):
self.pat = None
self.regex = None
self.flags = None
dict.__init__(self)
for d in ds:
self.update( d )
def popitem(self):
"""popitem doesn't make sense for this class"""
raise NotImplemented
def setdefault(self,key,default):
# print 'set default 1 %s %s' % (key, default)
new = not dict(self).has_key(key)
val = dict(self).get(key,default)
# print 'set default 2 %s %s %s' % (key,default, val)
if new:
dict.__setitem__(self,key,default)
self.compile()
return val
def update(self,newdict):
dict.update(self,newdict)
self.compile()
def __setitem__(self,key,val):
new = not dict(self).has_key(key)
dict.__setitem__(self,key,val)
if new:
self.compile()
def __delitem__(self,key):
dict.__delitem__(self,key)
self.compile()
def compile(self):
# print 'compile called'
if dict(self) and len(dict(self)) > 0:
tmp = "(%s)" % "|".join(map(re.escape,
dict(self).keys()))
if self.pat != tmp:
self.pat = tmp
if self.flags:
self.regex = re.compile(self.pat,self.flags)
else:
self.regex = re.compile(self.pat)
# not called from outside, but is needed by
# the sub below
# self.regex.sub(self,s) is regex.sub(func=self.__call__,s)
def __call__(self, match):
return dict(self)[match.group()]
def sub(self, s):
if len(dict(self)) == 0:
return s
return self.regex.sub(self, s)
if __name__ == "__main__":
text = "As you know, Bob, Larry Wall is the creator of Perl"
adict = {
"Larry Wall" : "Guido van Rossum",
"creator" : "Benevolent Dictator for Life",
"Perl" : "Python"
}
print 'start'
xlat = textsub(adict)
print 'Fred for Bob'
xlat["Bob"] = "Fred"
print 'set default is'
xlat.setdefault('is','really is')
print xlat.sub(text)
print """set default Bob, xlat['Bob'] is 'Fred'"""
print xlat.setdefault('Bob','Jay')
print xlat.sub(text)
print """del xlat['Bob'], setdefault"""
del xlat['Bob']
print xlat.setdefault('Bob','Jay')
print xlat.sub(text)
print 'del creator'
del xlat["creator"]
print xlat.sub(text)
print 'popitem'
try:
dummy1,dummy2 = xlat.popitem()
except NotImplemented:
print 'popitem not implemented'
else:
print 'oops'
print 'clear'
xlat.clear()
print xlat.sub(text)
More information about the Python-list
mailing list