deadlock
deadlock

Reputation: 7310

How to replace multiple words in a string through Python in a case insensitive way?

Lets say for example, I have the string:

s = 'Back in BLACK, I hit the sAck, I've been too LOng I'm glad to be back.'

In the above string, I want to search & replace certain words in a case insensitive way with the following words

black : b***

sack : s***

long : l***

glad : g***

I would like the resulting string to be

s = 'Back in B****, I hit the s***, I've been too L*** I'm glad to be back.'

Basically the above string maintains the case of the first letter of the word I am replacing. The letters after the word will trail with '*'

I'm assuming I would need to make a list of some sort with the replacements. In Django I am currently using the replace_all() function but it's case sensitive. So for words like BLACK and sAck, this becomes a daunting task since there are many combinations!

How can I go about doing this?

Upvotes: 2

Views: 3152

Answers (2)

Ned Batchelder
Ned Batchelder

Reputation: 375574

This is a bit dense, but works:

>>> re.sub(
        r"(?i)\b(black|sack|long|glad)\b", 
        lambda m: m.group()[0] + "*"*(len(m.group())-1), 
        s
        )
"Back in B****, I hit the s***, I've been too L*** I'm g*** to be back."

Upvotes: 2

Andrew Clark
Andrew Clark

Reputation: 208465

Use the re module, here is a brief example for "black":

>>> import re
>>> s = "Back in BLACK, I hit the sAck, I've been too LOng I'm glad to be back."
>>> regex = re.compile(r'black', flags=re.IGNORECASE)
>>> regex.sub('b***', s)
"Back in b***, I hit the sAck, I've been too LOng I'm glad to be back."

To keep the case of the first letter, capture it and use a back reference in the replacement:

>>> regex = re.compile(r'(b)lack', flags=re.IGNORECASE)
>>> regex.sub(r'\1***', s)
"Back in B***, I hit the sAck, I've been too LOng I'm glad to be back."

To do all the replacements in one pass:

>>> regex = re.compile(r'(?=(.))(?:black|sack|long|glad)', flags=re.IGNORECASE)
>>> regex.sub(r'\1***', s)
"Back in B***, I hit the s***, I've been too L*** I'm g*** to be back."

Upvotes: 5

Related Questions