flexible find and replace ?

Tim Chase python.list at tim.thechases.com
Mon Feb 16 22:36:17 CET 2009


> how would you do a clever find and replace, where the value replacing
> the tag
> is changing on each occurence ?
> 
> ".......TAG............TAG................TAG..........TAG....."
> 
> is replaced by this :
> 
> ".......REPL01............REPL02................REPL03..........REPL04..."



This is a variant of the class I've used in the past for stateful 
replacements:

   import re

   class Counter(object):
     def __init__(self, prefix="REPL", start=1):
     	self.prefix = prefix
     	self.counter = start - 1
     def __call__(self, matchobj):
     	self.counter += 1
     	return "%s%02i" % (self.prefix, self.counter)

   r = re.compile("TAG") # the regexp to find what we want
   s = "some TAG stuff with TAG whatever more TAG stuff"

   print s
   # just use the counter
   print r.sub(Counter(), s)
   # demo a different starting number
   print r.sub(Counter(start=42), s)
   # maintain a single counter across calls
   c = Counter(prefix="Hello", start=42)
   print r.sub(c, s)
   print r.sub(c, s)

> A better and clever method than this snippet should exist I hope :
> 
> counter = 1
> while 'TAG' in mystring:
>     mystring=mystring.replace('TAG', 'REPL'+str(counter), 1)
>     counter+=1
>     ...
> 
> (the find is always re-starting at the string beginning, this is not
> efficient.

This also has problems if your search-string is a substring of 
your replacement string:

   search = "foo"
   replacement = "foobar#"

You'll get

   s = "foo_foo"
   s = "foobar01_foo"
   s = "foobar02bar01_foo"
   ...

which isn't quite what it looks like you want.

-tkc






More information about the Python-list mailing list