Hi,

I am trying to write a python func. which can replace nth occurance of any substring present in any string.
For example:

main_string = "badZZZZZZZZZZZZZZZZZZbadZZZZZZZZZZZZZZZZZZZZzbadZZZZZZZZZZZZZZZZZ"

If I wanna replace the 2nd occurance of string "bad" with 'good' i will pass

customreplace(main_string,'bad','good',2)

So the Function should return

badZZZZZZZZZZZZZZZZZZgoodZZZZZZZZZZZZZZZZZZZZzbadZZZZZZZZZZZZZZZZZ

I have tried normal replace()

main_string.replace('bad','good',2)

. But its not what I wanted.

Thanks In Advance,

One way to do it would be to use re.sub with a function argument. That function could increase a counter every time it's called and then either return the given string unchanged or return the replacement string depending on whether the counter is equal to your n.

I tried Something like this, But the output is not what I wnated..

import re
main_string = "badZZZZZZZZZZZZZZZZZZbadZZZZZZZZZZZZZZZZZZZZzbadZZZZZZZZZZZZZZZZZ"
for i in range(0,main_string.count('bad')):
        print re.sub(r'bad','good',main_string,i)

Out Put is :

debasish@debasish:~$ python occ.py 
goodZZZZZZZZZZZZZZZZZZgoodZZZZZZZZZZZZZZZZZZZZzgoodZZZZZZZZZZZZZZZZZ
goodZZZZZZZZZZZZZZZZZZbadZZZZZZZZZZZZZZZZZZZZzbadZZZZZZZZZZZZZZZZZ
goodZZZZZZZZZZZZZZZZZZgoodZZZZZZZZZZZZZZZZZZZZzbadZZZZZZZZZZZZZZZZZ
debasish@debasish:~$ 

I want it to replace one "bad" string at a time..Can you please suggest

Thanks,

I think you may have misunderstood my suggestion. re.sub can be called with a function (or method or other callable object) as an argument. That function will be called with a match object as its argument for every occurrence of the pattern.

So you can define a function (or method) that keeps track of a counter to decide whether to perform the replacement or not. Then you can call re.sub with that function as its argument. No loop necessary.

I'm not sure whether that's the simplest solution to your problem, but it's the first that I thought of.

The only other simplish alternative that I can think of would be to loop over all indices in the string, check whether the pattern occurs at that index, increase the counter if so and add the replacement string to the result string and skip a number of character equal to the replacement's string's length if the counter is equal to your n - otherwise add the character at the current index to the result string (which is probably best represented as a list of strings that is joined after the loop). The version using re.sub is probably easier to implement though.

Another approach:

''' re_search_replace1.py
replace second 'bad' with 'good'
'''

import re

s = 'bad1234567bad12345678bad123456789'

print(s)  # test

m = re.search('bad', s)

# apply slicing
s1 = s[:m.end()]
s2 = s[m.end():]

print(s1)  # test
print(s2)  # test

s3 = s2.replace('bad', 'good', 1)

print(s3)  # test
print(s1+s3)

'''
bad1234567bad12345678bad123456789
bad
1234567bad12345678bad123456789
1234567good12345678bad123456789
bad1234567good12345678bad123456789
'''
Comments
That's nice. And simpler than my ideas.
This article has been dead for over six months. Start a new discussion instead.