Velocity Reviews > Iteration within re.sub()?

# Iteration within re.sub()?

Bryant Huang
Guest
Posts: n/a

 12-14-2004
Hi,

Is it possible to perform iteration within the re.sub() function call?

For example, if I have a string like:

str = "abbababbabbaaa"

and I want to replace all b's with an integer that increments from 0,
could I do that with re.sub()?

Replacing b's with 0's is trivial:

i = 0
pat = re.compile("b")
print pat.sub(`i`, str)

Now, how can I increment i in each replacement? Is this possible? Like,
using a lambda function, for example? Or do I use a different re
function altogether?

I use this trivial [ab]* language for simplicity, but I have a real
problem where I need to match a more complex regex and replace it with
an incrementing integer.

Thanks so much!
Bryant

Mark McEahern
Guest
Posts: n/a

 12-14-2004
Bryant Huang wrote:

>Hi,
>
>Is it possible to perform iteration within the re.sub() function call?
>
>

Sure. As the docs note:

If repl is a function, it is called for every non-overlapping occurrence
of pattern. The function takes a single match object argument, and
returns the replacement string. For example:

#!/usr/bin/env python

import re

class Counter:
def __init__(self):
self.count = -1
def increment(self, matchObject):
self.count += 1
return str(self.count)

text = "abbababbaaaaaabbaaa"
expected = "a01a2a34aaaaaa56aaa"

# Replace all b's with an integer that increments from 0.

c = Counter()
pat = re.compile("(b)")
actual = pat.sub(c.increment, text)
assert expected == actual

Bryant Huang
Guest
Posts: n/a

 12-14-2004
Ah beautiful, thank you both, Robert and Mark, for your instant and
helpful responses. I understand, so the basic idea is to keep a
variable that is globally accessible and call an external function to
increment that variable...

Thanks!
Bryant

Fredrik Lundh
Guest
Posts: n/a

 12-14-2004
Bryant Huang wrote:

> Ah beautiful, thank you both, Robert and Mark, for your instant and
> helpful responses. I understand, so the basic idea is to keep a
> variable that is globally accessible and call an external function to
> increment that variable...

accessible for the callback function, that is.

see Mark's example for the right way to do it (using a object to hold
the state, and an object method as the callback -- the latter is known
as a "bound method", and holds a reference to both the data (self) and
the code).

</F>