'Is it possible to ignore string in quotes for replace()?

Is it possible to ignore string in quotes for python replace()? I have a string variable like this:

a = "I like bananas 'I like bananas'"

I want to get a result like this via replace():

"I like apples 'I like bananas'".

But when I execute print(a.replace("bananas", "apples")),the result is:

"I like apples 'I like apples'".

How can I do to make replace() ignore string in quotes?



Solution 1:[1]

Split the string by ', process only the odd elements of the array, reassemble the string

a = "I like bananas 'I like bananas'"
ap = a.split("'")
ar = [ ai.replace("bananas", "apples")  if i%2==0 else ai for i,ai in enumerate(ap)]
print("'".join(ar))

Solution 2:[2]

Here is regexp example:

import re

text = "I like bananas 'I like bananas' 'I like also bananas'"

def replace2(orginal_text, b, c):
    pattern = re.compile(r".*? (\'.*?\')") # patternt to match text inside single quotes
    matches = []
    for match in pattern.findall(orginal_text): # match with pattern as many times pattern is found
        matches.append(match)
    for match in matches:
        replace_with = match.replace(b, c) # replace b with c in matched string
        orginal_text = re.sub(match, replace_with, orginal_text) # replace matched text with new string
    return orginal_text

result = replace2(text, "bananas", "apples")
print(result)

It will try to foind all text that are between single quotes. Then replaces the old string (b) with new (c) from the matches. Finally replaces the new edited matches from original string.

Solution 3:[3]

No, it is not possible, you cannot make replace ignore those matches. You will have to code your own solution.

Solution 4:[4]

You can use count value (optional parameter of the replace method) to specify how many occurrences of the old value you want to replace. It works fine for both.

a = "I like bananas \"I like bananas\""
print(a.replace("bananas", "apples",1))

a = "I like bananas 'I like bananas'" 
print(a.replace("bananas", "apples",1))

Output:

I like apples 'I like bananas'

Solution 5:[5]

It's absolutely possible, this is complete answer for this question :

import re
original_str = "I like bananas 'I Love banana'  somthing  'I like banana'  I love banana ' I like babana again' "
pattern = r"('(.+?)')"
replaced_str = ''
quoted_strings = re.compile(pattern)
newstring = "foo"
x_start = 0
print("original_str = (", original_str+")\n")
for m in quoted_strings.finditer(original_str):
    print(m.span(), m.group())
    x_end, x_next = m.span() 
    w = original_str[x_start:x_end]
    w = w.replace("banana", "apple")
    replaced_str = replaced_str + w + original_str[x_end:x_next]
    x_start = x_next
print(replaced_str)

output :

original_str = ( I like bananas 'I Love banana'  somthing  'I like banana'  I love banana ' I like babana again' )

(15, 30) 'I Love banana'
(42, 57) 'I like banana'
(73, 95) ' I like babana again'
I like apples 'I Love banana'  somthing  'I like banana'  I love apple ' I like babana again'

Solution 6:[6]

As per your update to your requirements in your reply to gnight

a = "I like bananas 'I like \'bananas\' ' "
print (a)

Gives:
I like bananas 'I like 'bananas' '
as the \' gets converted to ' when run, that is it is the same as
a = "I like bananas 'I like 'bananas' ' "

as gnight says the only real option is to only replace in the first and last sections of the string that arent in quotes, Ie

a = "I like bananas 'I like \'bananas\' ' "
ap = a.split("'")
if len(ap)>0:
    ap[0]=ap[0].replace("bananas", "apples")
if len(ap)>1:
    ap[-1]=ap[-1].replace("bananas", "apples")
print("'".join(ap))

that gives:
I like apples 'I like 'bananas' '

In the past i have written parsers to handle tripple quote escaping that excel uses and a state machine to track the quote state, not fun to implement if you end up having to do that.

If you can give some more examples of desired input an output it may help

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 JariK
Solution 3 Tim-Erwin
Solution 4 Python learner
Solution 5 Koorosh Torabi
Solution 6