re

Jeff Epler jepler at unpythonic.net
Tue May 28 15:22:11 EDT 2002


On Tue, May 28, 2002 at 07:34:33PM +0100, Eric Texier wrote:
> Well, I am not completly new at python but some module (no mater what
> language: it started with sed)
> are impossible to get a good grab on:
> 
> I am trying to do replace '#' with a number in string with some control
> over the padding:
> 
> a = 'echo file#.sgi file#~3.sgi file#~5*2.sgi'
> 
> ex: with 3
> newString = "file3.sgi file003.sgi file00006.sgi"
> 
> 
> # -> number
> #~x ->   number with some 0 in front for padding
> #*2+3 -> number * 2 + 3 etc...
> 
> If this is trivial for one of you, I will appreciate your help a lot.
> 
> Thanks.

    import re

You can use the RE module to find your replacement pattern.  A suitable
regular expression would be
    pat = re.compile("#(~[0-9]+)?(\\*[0-9]+)?")

Then, you can use the following class to perform the replacement:
    class Replacer:
	def __init__(self, n):
	    self.n = n

	def __call__(self, match):
	    n = self.n
	    if match.group(1): # was the width specified?
		fmt = "%%0%sd" % (match.group(1)[1:])
	    else:
		fmt = "%d"
	    if match.group(2): # was the multiplier group specified?
		n = n * int(match.group(2)[1:])
	    return fmt % n

Does it work?
>>> pat.sub(Replacer(3), "echo file#.sgi file#~3.sgi file#~5*2.sgi")
'echo file3.sgi file003.sgi file00006.sgi'

To understand how the program works, you'll need to read the doc sections on
Regular Expression syntax and objects, Match objects, understand classes
and the __call__ special method.

Instead of using a Replacer class, there are other ways of writing it.
For instance,
    def replacer(match, n):
	# almost like __call__ above
    n = 3
    pat.sub(lambda match, n=n: replacer(match, n), ...)
Or, with nested scopes (2.2 and higher):
    pat.sub(lambda match: replacer(match, n), ...)
It's up to you whether the 'class' approach is better.  I believe it is,
because you can easily put additional information inside the class
instance (a default width, perhaps?  a flag to use a hex or octal
number?) and because classes are a much more important concept than
'lambda's.

Jeff





More information about the Python-list mailing list