Artyom Lisovskij Artyom Lisovskij - 29 days ago 12
Python Question

How can i generate text using patterns with multiple nesting?

I got pattern such as:


{In my {beautiful|wonderful} world i'm {the best one|looser}|Not today, {man|guy}}


And want to get random results:


In my wonderful world i'm looser

In my beautiful world i'm the best one

Not today, guy

In my wonderful world i'm the best one

...


and so on. I've got working code for one-level nesting pattern:

import random
import re

def replace_random(review):
random_tags = re.findall(r"\{(.*?)\}", review, re.DOTALL)
for random_tag in random_tags:
choice = random.choice(random_tag.split('|'))
review = review.replace('{'+random_tag+'}', choice)
return review

print(replace_random('In my {beautiful|wonderful} world i\'m {the best one|looser}'))


But if i have multiple nesting(as above), it doesn't work. How to make it recursively?

Answer

Replace the inner tags that don't contain any curly brackets, and then if there's any tags left, repeat the process:

import random
import re

def replace_random(review):
    random_tags = re.findall(r"\{([^{}]*?)\}", review, re.DOTALL)
    for random_tag in random_tags:
        choice = random.choice(random_tag.split('|'))
        review = review.replace('{' + random_tag + '}', choice)
    if '{' in review or '}' in review:
        return replace_random(review)
    return review

print(replace_random("{In my {beautiful|wonderful} world i'm {the best one|looser}|Not today, {man|guy}}"))

Like your current code, this will have problems if you want to have literal curly brackets in your output. It's also not the most efficient way as it does work that will often be thrown away. But it will probably be fine.