Case Sensitive String Replacement In Python
Solution 1:
fromstringimport maketrans
"Abc".translate(maketrans("abcABC", "defDEF"))
Solution 2:
Here's a method using regular expressions. The key point is that when it finds a match it first modifies the replacement string to match the casing of the matched string. This works because re.sub
can take a function as a replacement instead of just a string.
import re
defcase_sensitive_replace(s, before, after):
regex = re.compile(re.escape(before), re.I)
return regex.sub(lambda x: ''.join(d.upper() if c.isupper() else d.lower()
for c,d inzip(x.group(), after)), s)
test = '''
abc -> def
Abc -> Def
aBc -> dEf
abC -> deF
'''
result = case_sensitive_replace(a, 'abc', 'def')
print(result)
Result:
def -> def Def -> Def dEf -> dEf deF -> deF
Solution 3:
Expanding on Mark Byers' answer, Here's a solution which works for replacement text of any length. The trick is to send a function to re.sub().
import re
def case_sensitive_replace(string, old, new):
""" replace occurrences of old with new, within string
replacements will match the case of the text it replaces
"""
def repl(match):
current= match.group()
result=''
all_upper=Truefor i,c in enumerate(current):
if i >= len(new):
break
if c.isupper():
result+=new[i].upper()
else:
result+=new[i].lower()
all_upper=False
#append any remaining characters fromnew
if all_upper:
result+=new[i+1:].upper()
else:
result+=new[i+1:].lower()
returnresult
regex = re.compile(re.escape(old), re.I)
return regex.sub(repl, string)
print case_sensitive_replace("abc Abc aBc abC ABC",'abc','de')
print case_sensitive_replace("abc Abc aBc abC ABC",'abc','def')
print case_sensitive_replace("abc Abc aBc abC ABC",'abc','defg')
Result:
de De dE de DE
defDef dEf deF DEF
defg Defg dEfg deFg DEFG
Solution 4:
Long time lurker, thought I'd post a suggestion here as some of these seem fairly convoluted.
print map(lambda a, b: b.lower() if a.islower() else b.upper(), "aBc", "def")
It does assume both strings are the same length, however you could easily replace the lambda with a proper function and check for None on the first input.
Solution 5:
Not the most efficient way, and it's very crude, but probably something like this could work:
def case_insensitive_replace(string, old, new):
upper_indices = [idx for idx, charinenumerate(string) ifchar.isupper()]
replaced = list(string.lower().replace(old.lower(), new.lower()))
for idx in upper_indices:
replaced[idx] = replaced[idx].upper()
return"".join(replaced)
Post a Comment for "Case Sensitive String Replacement In Python"