Skip to content Skip to sidebar Skip to footer

Case Sensitive String Replacement In Python

I need to replace a string in case sensitive way. For example abc -> def Abc -> Def aBc -> dEf abC -> deF What can I do this with 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"