10

I have a user entered string and I want to search it and replace any occurrences of a list of words with my replacement string.

import re

prohibitedWords = ["MVGame","Kappa","DatSheffy","DansGame","BrainSlug","SwiftRage","Kreygasm","ArsonNoSexy","GingerPower","Poooound","TooSpicy"]


# word[1] contains the user entered message
themessage = str(word[1])    
# would like to implement a foreach loop here but not sure how to do it in python
for themessage in prohibitedwords:
    themessage =  re.sub(prohibitedWords, "(I'm an idiot)", themessage)

print themessage

The above code doesn't work, I'm sure I don't understand how python for loops work.

1
  • You should try checking out spambayes implementation for python might be more scalable . Commented Mar 27, 2013 at 12:18

4 Answers 4

41

You can do that with a single call to sub:

big_regex = re.compile('|'.join(map(re.escape, prohibitedWords)))
the_message = big_regex.sub("repl-string", str(word[1]))

Example:

>>> import re
>>> prohibitedWords = ['Some', 'Random', 'Words']
>>> big_regex = re.compile('|'.join(map(re.escape, prohibitedWords)))
>>> the_message = big_regex.sub("<replaced>", 'this message contains Some really Random Words')
>>> the_message
'this message contains <replaced> really <replaced> <replaced>'

Note that using str.replace may lead to subtle bugs:

>>> words = ['random', 'words']
>>> text = 'a sample message with random words'
>>> for word in words:
...     text = text.replace(word, 'swords')
... 
>>> text
'a sample message with sswords swords'

while using re.sub gives the correct result:

>>> big_regex = re.compile('|'.join(map(re.escape, words)))
>>> big_regex.sub("swords", 'a sample message with random words')
'a sample message with swords swords'

As thg435 points out, if you want to replace words and not every substring you can add the word boundaries to the regex:

big_regex = re.compile(r'\b%s\b' % r'\b|\b'.join(map(re.escape, words)))

this would replace 'random' in 'random words' but not in 'pseudorandom words'.

Sign up to request clarification or add additional context in comments.

9 Comments

You'd have to break it up if you had lots of words to replace, though.
You might want to enclose your expression in \b's to avoid replacing "tail" in "retailers".
I get a weird repeated string when I use this (the entire line prints twice)
@Zac It works well for me. Can you edit your answer and show what are you doing and the output you obtain?
It works after a restart, there was some weird code going on after I'd done a previous syntax error and python had crashed. But after the restart the code works great. Thx.
|
6

try this:

prohibitedWords = ["MVGame","Kappa","DatSheffy","DansGame","BrainSlug","SwiftRage","Kreygasm","ArsonNoSexy","GingerPower","Poooound","TooSpicy"]

themessage = str(word[1])    
for word in prohibitedwords:
    themessage =  themessage.replace(word, "(I'm an idiot)")

print themessage

2 Comments

This is brittle: as Bakuriu explained, it easily breaks when one of the prohibited words is a substring of another.
@codesparkle it doesn't mean that is wrong, you always choose your option depends on certain conditions
2

Based on Bakariu's answer,

A simpler way to use re.sub would be like this.

words = ['random', 'words']
text = 'a sample message with random words'

new_sentence = re.sub("random|words", "swords", text)

The output is "a sample message with swords swords"

Comments

0

Code:

prohibitedWords =["MVGame","Kappa","DatSheffy","DansGame",
                  "BrainSlug","SwiftRage","Kreygasm",
                  "ArsonNoSexy","GingerPower","Poooound","TooSpicy"]
themessage = 'Brain'   
self_criticism = '(I`m an idiot)'
final_message = [i.replace(themessage, self_criticism) for i in prohibitedWords]
print final_message

Result:

['MVGame', 'Kappa', 'DatSheffy', 'DansGame', '(I`m an idiot)Slug', 'SwiftRage',
'Kreygasm', 'ArsonNoSexy', 'GingerPower', 'Poooound','TooSpicy']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.