change only the nth occurrence of a pattern in a string

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Wed Dec 31 10:33:54 EST 2008


On Wed, 31 Dec 2008 15:40:32 +0100, TP wrote:

> Hi everybody,
> 
> 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)?

Step 1: Find the nth occurrence.
Step 2: Change it.


def findnth(source, target, n):
    num = 0
    start = -1
    while num < n:
        start = source.find(target, start+1)
        if start == -1: return -1
        num += 1
    return start

def replacenth(source, old, new, n):
    p = findnth(source, old, n)
    if n == -1: return source
    return source[:p] + new + source[p+len(old):]


And in use:

>>> replacenth("abcabcabcabcabc", "abc", "WXYZ", 3)
'abcabcWXYZabcabc'


> Why this default behavior? For the user, it would be easier to put
> re.sub or replace in a loop to change the first n occurences.

Easier than just calling a function? I don't think so.

I've never needed to replace only the nth occurrence of a string, and I 
guess the Python Development team never did either. Or they thought that 
the above two functions were so trivial that anyone could write them. 



-- 
Steven



More information about the Python-list mailing list