Skip to content
Advertisement

Python ignore already replaced string / replace string not already replaced

Is there a way to identify an already converted/replaced string and not allow it to replace again?

from_str = ['given name','name']
to_str = ['{first_name}','{family_name}']

in_str = "My given name is not my name"

for ind, char in enumerate(from_str):
    in_str = in_str.replace(from_str[ind],to_str[ind])

print(in_str)

This give result as My {first_{family_name}} is not my {family_name}

I want result like:

My {first_name} is not my {family_name}.

Advertisement

Answer

You can’t ignore it. Python is searching for ‘name’, and ‘first_name’ contains the word ‘name’ on it.

You have at least two options:

Option #1

Do a double replacement. Replace first with something you’re sure you’re not going to write, then replace it again with the end string.

from_str = ['given name','name']
to_str = ['{first_name}','{family_name}']

in_str = "My given name is not my name"

for ind, char in enumerate(from_str):
    in_str = in_str.replace(char,f'{{{ind}}}')

# in_str at this point: My {0} is not my {1}


for ind, replacement in enumerate(to_str):
    in_str = in_str.replace(f'{{{ind}}}',replacement)

print(in_str) # My {first_name} is not my {family_name}

Option #2

Write a regex that helps you cover those cases. In your example, a reasonable regular expression could be looking for word boundaries around the selected words. This way, it’ll only replace exact matches that contain spaces, punctuation or the start/end of the string around them.

import re

from_str = ['given name','name']
to_str = ['{first_name}','{family_name}']

in_str = "My given name is not my name"

for ind, char in enumerate(from_str):
    in_str = re.sub(rf'b{char}b',to_str[ind],in_str)

print(in_str) # My {first_name} is not my {family_name}
Advertisement