You must make the matching case-insensitive.
You can include the flag in the pattern, as in:
import re
variants = ["I have apple.", "I have Apple.", "I have APPLE and aPpLe."]
def replace_apple_insensitive(s):
# Adding (?i) makes the matching case-insensitive
return re.sub(r'(?i)(apple)', r'(\1)', s)
for s in variants:
print(s, '-->', replace_apple_insensitive(s))
# I have apple. --> I have (apple).
# I have Apple. --> I have (Apple).
# I have APPLE and aPpLe. --> I have (APPLE) and (aPpLe).
Or you can compile the regex and keep the case-insensitive flag out of the pattern:
apple_regex = re.compile(r'(apple)', flags=re.IGNORECASE) # or re.I
print(apple_regex.sub(r'(\1)', variants[2]))
#I have (APPLE) and (aPpLe).
IGNORECASEflag. docs.python.org/2/howto/regex.html#compilation-flags