1

I have searched for an answer. I am sure they are out there, but there are way too many false hits.

This is my script (my attempt fails):

#!/bin/env python

import re

usage="""
    My favorite restaurant is <<<res>>>
    My favorite person is <<<per>>>
"""

res="pizza hut"
per="my sister"

def main():
    value = re.sub(r'<<<(\w+)>>>', globals()[r'\1'], usage)
    print 'value=%s.' % (value)

if ( __name__ == "__main__"):
    main()

What I am trying to output is:

value=
    My favorite restaurant is pizza hut
    My favorite person is my sister
.

The closest answer that I have seen, involves maintaining a separate list. I do not want to have to maintain a separate list.

1
  • Why are you using globals() here? There is no global name \1 in your code (nor could there be). Commented Nov 7, 2013 at 17:01

4 Answers 4

2

You can use a function as the replacement in re.sub(). The function will receive the match object as the only argument and should return a string. The best way to do this is to create a dictionary with your replacements:

import re

usage="""
    My favorite restaurant is <<<res>>>
    My favorite person is <<<per>>>
"""

rep = {"res": "pizza hut",
       "per": "my sister"}

print re.sub(r'<<<(\w+)>>>', lambda m: rep.get(m.group(1), ""), usage)

You could use this exact same method with globals(), but using globals() in this way is generally discouraged when a dictionary offers the same behavior in a safer way.

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

2 Comments

ahhh you beat me :P by alot ... how did I not see this (+1)
Thanks for the answer. I tried it and it worked, so I gave you an upvote!
2

Use a dict instead of using variables, and change <<<res>>> to {res} using regex so that you can use string formatting on it:

>>> import re
>>> usage="""                                   
    My favorite restaurant is <<<res>>>
    My favorite person is <<<per>>>
"""
>>> my_dict = {'res':'pizza hut', 'per':'my sister'}
>>> print re.sub(r'<<<(\w+)>>>', r'{\1}', usage).format(**my_dict)

    My favorite restaurant is pizza hut
    My favorite person is my sister

Comments

1

This is a dangerous way using eval:

def repl(match):
    return eval(match.group(0)[3:-3])

print re.sub(r'<<<\w+>>>', repl, usage)

Output:

My favorite restaurant is pizza hut
My favorite person is my sister

3 Comments

Wait, out of all the answers you choose the one with eval()?
The closest answer that I have seen, involves maintaining a separate list. I do not want to have to maintain a separate list. I gave the solution without using a separate list or dict.
Yes this is the closest to what I wanted.
1

Are you free to modify the formatting? Python already supports this by doing:

usage = """
    My favorite restaurant is {res}
    My favorite person is {per}
"""
res = "pizza hut"
per = "my sister"

print usage.format(**globals())

2 Comments

Thanks for the answer. I tried it and it worked, so I gave you an upvote!
I do not know that my final usage string might need to have a "{some stuff}" pattern in it that is not a intended for replacement. Because of this I might have to change the replacement pattern to insure all are intended to be replaced by variable values. I want to be able to change this (i.e. to __VAR(???)__, instead of <<<???>>>).

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.