Use negative lookahead like below.
>>> s = "cat goose mouse horse pig cat cow"
>>> re.sub(r'^((?:(?!cat).)*cat(?:(?!cat).)*)cat', r'\1Bull', s)
'cat goose mouse horse pig Bull cow'
^
Asserts that we are at the start.(?:(?!cat).)*
Matches any character but not ofcat
, zero or more times.cat
matches the firstcat
substring.(?:(?!cat).)*
Matches any character but not ofcat
, zero or more times.- Now, enclose all the patterns inside a capturing group like
((?:(?!cat).)*cat(?:(?!cat).)*)
, so that we could refer those captured chars on later. cat
now the following secondcat
string is matched.
OR
>>> s = "cat goose mouse horse pig cat cow"
>>> re.sub(r'^(.*?(cat.*?){1})cat', r'\1Bull', s)
'cat goose mouse horse pig Bull cow'
Change the number inside the {}
to replace the first or second or nth occurrence of the string cat
To replace the third occurrence of the string cat
, put 2
inside the curly braces ..
>>> re.sub(r'^(.*?(cat.*?){2})cat', r'\1Bull', "cat goose mouse horse pig cat foo cat cow")
'cat goose mouse horse pig cat foo Bull cow'