39

I have a string, s = 'sdfjoiweng%@$foo$fsoifjoi', and I would like to replace 'foo' with 'bar'.

I tried re.sub(r'\bfoo\b', 'bar', s) and re.sub(r'[foo]', 'bar', s), but it doesn't do anything. What am I doing wrong?

3
  • 1
    print re.sub(r'\bfoo\b', 'bar', s) is correctly giving me sdfjoiweng%@$bar$fsoifjoi Commented Oct 12, 2016 at 16:11
  • 1
    perhaps you are mistakenly expecting s to be modified in place? Strings in Python are immutable. The new modified string will be returned by re.sub. Commented Oct 12, 2016 at 16:15
  • 1
    Sorry about the confusion, I am a beginner with regex and completely forgot that the string could not be modified in place. I retested my original code, and yes, it does work. Commented Oct 12, 2016 at 16:45

4 Answers 4

49

You can replace it directly:

>>> import re
>>> s = 'sdfjoiweng%@$foo$fsoifjoi'
>>> print(re.sub('foo','bar',s))
sdfjoiweng%@$bar$fsoifjoi

It will also work for more occurrences of foo like below:

>>> s = 'sdfjoiweng%@$foo$fsoifoojoi'
>>> print(re.sub('foo','bar',s))
sdfjoiweng%@$bar$fsoibarjoi

If you want to replace only the 1st occurrence of foo and not all the foo occurrences in the string then alecxe's answer does exactly that.

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

3 Comments

I'm not sure if OP is okay with foo being replaced in parts of words, like in your second case.
Plus, why re.sub() then and not replace()?
@alecxe, I totally agree with you that replace also could be used instead - as it is considered more readable, but the OP asked specifically for regex. As for the first comment the OP should specify if he wants foo being replaced in parts of words.
7

re.sub(r'\bfoo\b', 'bar', s)

Here, the \b defines the word boundaries - positions between a word character (\w) and a non-word character - exactly what you have matching for foo inside the sdfjoiweng%@$foo$fsoifjoi string. Works for me:

In [1]: import re

In [2]:  s = 'sdfjoiweng%@$foo$fsoifjoi'

In [3]: re.sub(r'\bfoo\b', 'bar', s)
Out[3]: 'sdfjoiweng%@$bar$fsoifjoi'

1 Comment

My only problem with \b that it doesn't work when spaces are the bounderies around the word. Do you have some solution on it? e.g. s = 'sdfjoiweng%@$foo foo $fsoifjoi' won't work
5

You can use replace function directly instead of using regex.

>>> s = 'sdfjoiweng%@$foo$fsoifjoifoo'
>>>
>>> s.replace("foo","bar")
'sdfjoiweng%@$bar$fsoifjoibar'
>>>
>>>

Comments

1

To further add to the above, the code below shows you how to replace multiple words at once! I've used this to replace 165,000 words in 1 step!!

Note \b means no sub string matching..must be a whole word..if you remove it then it will make sub-string match.

import re
s = 'thisis a test'
re.sub('\bthis\b|test','',s)

This gives:

'thisis a '

8 Comments

My only problem with \b that it doesn't work when spaces are the bounderies around the word. So e.g: re.sub('\bthis\b|test', '', 'thisis this a test') results in thisis this a Do you have some solution on it?
I want to get thisis a as a result. So I want to replace the 2nd this in the string.
More understandable example: thisis this this a test to thisis that that a that
Oh great thanks :-)...I would have suggested a 2 step approach to fix the problem but seems you found a solution already...can you please post your solution so that I'd learn from it too? :-)
This is my solution: re.sub("\bthis\b|test", "Q", re.sub(" this ", " Q ", "thisis this is a test")) It is a nested van, as I talked about a nested solution, but of course it can be a two liner as well (as I actually did it). The result: thisis Q is a Q
|

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.