Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RegEx for replacing specific words not between quotation marks

I'm trying to replace Hello in the string swith another word if the word is NOT between quotations marks such as " " or ' '. Let us pretend the replacement word is Matt so,

This is the input:

s = 'Hello How Are you, "hey Hello", \'ney Hello\'. Hello I\'m great'

Desired output:

s = 'Matt How are you, "hey Hello", \'ney Hello\'. Matt I\'m great '

I have searched around and come across this code and with little modification I manage to replace the word successfully but it only works with ' ' and not " " included

import re

def replace_method(match):

    if match.group(1) is None:
        return match.group()

    return match.group().replace("Hello", "Matt")

s = 'Hello How Are you, "hey Hello", \'ney Hello\'. Hello I\'m great'

output = re.sub(r"'[^']*'|([^']*)", replace_method, s)
print(output)

Edit:

Thanks for the answers, but I missed to explain something important (which I first noticed, in my defense, after executing the successful code), "obviously" I don't want this sentence:

s = "Hellona, how are you"

to become

s = "Markna, how are you"

So, the regex should include that the word I'm trying to replace is not surronded by NUMBERS or LETTERS.

like image 989
Frederik Avatar asked Dec 09 '25 05:12

Frederik


2 Answers

import re


def replace_word(input, search, replace):
    def replace_method(match):
        if match.group(2) is None:
            return match.group()
        return match.group(2).replace(search, replace)
    expr = re.compile("('[^']*'|\"[^\"]*\")|({})".format(search))
    return re.sub(expr, replace_method, s)

s = 'Hello How Are you, "hey Hello", \'ney Hello\'. Hello I\'m great'

output = replace_word(s, "Hello", "Matt")
print(output)

You can match everything between single or double quotes in group 1(('[^']*'|\"[^\"]*\")), then your word in group 2 ({}, formatted with the search term), then replace group 2 with whatever you want.

like image 191
Benoit Dufresne Avatar answered Dec 10 '25 19:12

Benoit Dufresne


The replacement callback looks fine.

The regex though, needs to be this

r"('[^']*'|\"[^\"]*\")|\b[Hh]ello\b"

Readable version

   (                             # (1 start)
        ' [^']* '
     |  
        " [^"]* "
   )                             # (1 end)
|  
   \b [Hh]ello \b

Note that I think the group 1 check in the callback
has to be true if group 1 matched.

Not a Python programmer, but should it be something like

if match.group(1) :
    return match.group()
return "Matt"

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!