I would like to change only the nth occurence of a pattern in
a string. The problem with "replace" method of strings, and
"re.sub" is that we can only define the number of occurrences
to change from the first one.
v="coucou"
v.replace("o","i",2)
'ciuciu'
import re
re.sub( "o", "i", v,2)
'ciuciu'
re.sub( "o", "i", v,1)
'ciucou'
What is the best way to change only the nth occurence
(occurrence number n)?
Well, there are multiple ways of doing this, including munging
the regexp to skip over the first instances of a match.
Something like the following untested:
re.sub("((?:[^o]*o){2})o", r"\1i", s)
However, for a more generic solution, you could use something like
import re
class Nth(object):
def __init__(self, n_min, n_max, replacement):
#assert n_min <= n_max, \
# "Hey, look, I don't know what I'm doing!"
if n_max > n_min:
# don't be a dope
n_min, n_max = n_max, n_min
self.n_min = n_min
self.n_max = n_max
self.replacement = replacement
self.calls = 0
def __call__(self, matchobj):
self.calls += 1
if self.n_min <= self.calls <= self.n_max:
return self.replacement
return matchobj.group(0)
s = 'coucoucoucou'
print "Initial:"
print s
print "Just positions 3-4:"
print re.sub('o', Nth(3,4,'i'), s)
for params in [
(1, 1, 'i'), # just the 1st
(1, 2, 'i'), # 1-2
(2, 2, 'i'), # just the 2nd
(2, 3, 'i'), # 2-3
(2, 4, 'i'), # 2-4
(4, 4, 'i'), # just the 4th
]:
print "Nth(%i, %i, %s)" % params
print re.sub('o', Nth(*params), s)
Why this default behavior?
Can't answer that one, but with so many easy solutions, it's not
been a big concern of mine.
-tkc
--
http://mail.python.org/mailman/listinfo/python-list