For a string
s = '{{a,b}} and {{c,d}} and {{0,2}}'
I'd like to replace every {{...}} pattern by randomly one of the items in the list inside, i.e.:
"a and d and 2"
"b and d and 0"
"b and c and 0"
...
I remember that there's a way in module re to not simply replace like re.sub, but have a custom replacement function, but I can't find this anymore in the doc (maybe I'm searching with wrong keywords...)
This doesn't give any output:
import re
r = re.match('{{.*?}}', '{{a,b}} and {{c,d}} and {{0,2}}')
for m in r.groups():
print(m)
2 Answers 2
You could use
import random, re
def replace(match):
lst = match.group(1).split(",")
return random.choice(lst)
s = '{{a,b}} and {{c,d}} and {{0,2}}'
s = re.sub(r"{{([^{}]+)}}", replace, s)
print(s)
Or - if you're into one-liners (not advisable though):
s = re.sub(
r"{{([^{}]+)}}",
lambda x: random.choice(x.group(1).split(",")),
s)
answered Apr 7, 2020 at 14:47
Jan
43.3k11 gold badges57 silver badges87 bronze badges
Sign up to request clarification or add additional context in comments.
Comments
You can avoid splitting using appropriate regex to fetch patterns:
import re, random
s = '{{a,b}} and {{c,d}} and {{0,2}}'
s = re.sub(r'{{(.*?),(.*?)}}', random.choice(['\1円', '\2円']), s)
# a and c and 0
answered Apr 7, 2020 at 14:52
Austin
26.1k4 gold badges28 silver badges52 bronze badges
2 Comments
lang-py
re.subdocs have an example of using a function forrepl. Also be aware that{}have special meaning within regex and will need to be escaped if you want a literal match.{{.*?}}is a valid pattern. No need to escape anything. It is not Android or C++ (MSVC).