Use a regular expression:
In [16]: re.sub(r'(?: |^)(abc),',r'!+\1+!,', s, flags=re.I)
Out[16]: '!+abc+!,!+Abc+!,!+aBc+!, abc-def, abca'
The patter (?: |^)(abc),
will match every abc
that proceeds by a space or the start of the string (^
) and followed by a comma and replaces it with the first captured group surrounded with your expected characters. Note that :?
in the first group makes it a non-captured group so the \1
will refer to abc
. Also we are using re.I
flag which is the ignore case flag.
If you also want to keep the spaces just use a captured-group for the first group:
In [19]: re.sub(r'( |^)(abc),',r'\1!+\2+!,', s, flags=re.I)
Out[19]: '!+abc+!, !+Abc+!, !+aBc+!, abc-def, abca'
Also note that if you want to pass multiple regex as the replacing pattern you can compile the first regex using re.compile()
and pass the other patterns within a loop:
my_regex = re.compile(r'( |^)(abc),')
my_new_result = [my_regex.sub(pattern, s, flags=re.I) for pattern in list_of_patterns]
As a more flexible way to deal with re.sub
you can also pass a function as the replacer, and so more operations on your captured strings. For example if you want to lower case the matched strings:
s = "abc, Abc, aBc (abc) abc abc <abc> abc-def, abca"
In [31]: re.sub(r'(^|\W)(abc)($|\W)', lambda x: '{}!+{}+!{}'.format(*x.groups()).lower() if x.group(3) != '-' else x.group(0), s, flags=re.I)
Out[31]: '!+abc+!, !+abc+!, !+abc+! (!+abc+!) !+abc+! abc <!+abc+!> abc-def, abca'