Reputation: 805
This question seems to have been asked several times for other languages. I have a sql-like script which has placeholders like "@@Variable1@@", "@@Variable2@@" and so on. I also have a dictionary in python with the values of these parameters. I need to replace the occurrences of the keys (in this dictionary) in the text file with the key's particular value from the dictionary. While I can loop through the dictionary and do this using some text replacement command, is there a more organized way (like a lib) of doing this.
Upvotes: 1
Views: 4588
Reputation: 858
Using re.sub
will be most elegant and efficient for this task.
This single line is enough to do the job:
re.sub(r"@@(\w+)@@", lambda match: parameter_values_dict[match.group(1)], input_text)
Here is complete solution:
>>> import re
>>> parameter_values_dict = {"variable1":"VAR1", "variable2":"VAR2"}
>>> input_text = "some text @@variable1@@ some more text @@variable2@@ some extra text"
>>> output_text = re.sub(r"@@(\w+?)@@", lambda match: parameter_values_dict[match.group(1)], input_text)
>>> print(output_text)
some text VAR1 some more text VAR2 some extra text
Upvotes: 3
Reputation: 13049
I don't know of a library, but here is how you might do the substitution yourself.
You wouldn't really want to loop through keys in the dictionary as then you will have to scan the text multiple times -- instead you can use re.sub
and look up in the dictionary (which is quick) each time that you find a string contained between pairs of @@
. This way you only scan through the text once.
You probably need to decide what to do if the match is not found, but here is an example.
import re
def from_dict(dct):
def lookup(match):
key = match.group(1)
return dct.get(key, f'<{key} not found>')
return lookup
subs = {"name": "John",
"age": "40"}
text = "Name: @@name@@ Age: @@age@@ Occupation: @@occupation@@"
print(re.sub('@@(.*?)@@', from_dict(subs), text))
This gives:
Name: John Age: 40 Occupation: <occupation not found>
A slightly longer but maybe more efficient equivalent of the get
would be an explicit test:
return dct[key] if key in dct else f'<{key} not found>'
which saves formatting the string if in fact the key is found.
Upvotes: 3