Генерация текста по заданному шаблону - PullRequest
0 голосов
/ 29 сентября 2019

Например, у меня есть строка, такая как

    text = '{Hello|Good morning|Hi}{. We|, we} have a {good |best }offer for you.'

Как мне создать набор всех возможных строк с вариантами слов в фигурных скобках?

Hello.У нас есть хорошее предложение для вас.

Доброе утро, у нас есть лучшее предложение для вас.

и т.д ...

Ответы [ 2 ]

0 голосов
/ 29 сентября 2019

Я бы использовал метод обхода дерева, чтобы получить все возможные варианты:

import re
text = '{Hello|Good morning|Hi}{. We|, we} have a {good |best }offer for you.'
variants = ['']
elements = re.split(r'([{\|}])',text)

inside = False
options = []
for elem in elements:
    if elem=='{':
        inside = True
        continue
    if not inside:
        variants = [v+elem for v in variants]
    if inside and elem not in '|}':
        options.append(elem)
    if inside and elem=='}':
        variants = [v+opt for opt in options for v in variants]
        options = []
        inside = False

print(*variants,sep='\n')

Вывод:

Hello. We have a good offer for you.
Good morning. We have a good offer for you.
Hi. We have a good offer for you.
Hello, we have a good offer for you.
Good morning, we have a good offer for you.
Hi, we have a good offer for you.
Hello. We have a best offer for you.
Good morning. We have a best offer for you.
Hi. We have a best offer for you.
Hello, we have a best offer for you.
Good morning, we have a best offer for you.
Hi, we have a best offer for you.

Объяснение: Я использую re.split дляразбить str на элементы:

['', '{', 'Hello', '|', 'Good morning', '|', 'Hi', '}', '', '{', '. We', '|', ', we', '}', ' have a ', '{', 'good ', '|', 'best ', '}', 'offer for you.']

Затем я создаю флаг inside, который я буду использовать для хранения, если в данный момент нахожусь внутри или снаружи { и }, и действовать соответственно.

  • Если я нахожу {, я устанавливаю флаг и перехожу к следующему элементу (continue)
  • Если я не в скобках, я просто добавляю данный элемент к каждому варианту.
  • Если я внутри, а элементы не { и не |, я добавляю этот элемент в список options.
  • Если я нахожусь внутри и нахожу }, то я сделал варианты для каждой возможной части (одного из вариантов), (один из вариантов), и варианты становятся результатом этой операции.

Обратите внимание, что я предполагаю, что: всегда правильно str будет дано как text, а { будет использоваться исключительно как управляющий символ, а } будет использоваться исключительно как управляющий символ и | внутри {} будет использоваться исключительно как управляющий символ.

0 голосов
/ 29 сентября 2019

Вы можете использовать модуль re и random, например:

import random
import re

def randomize(match):
    res = match.group(1).split('|')
    random.shuffle(res)
    return res[0]

def random_sentence(tpl):
    return re.sub(r'{(.*?)}', randomize, tpl)

tpl = '{Hello|Good morning|Hi}{. We|, we} have a {good |best }offer for you.'
print(random_sentence(tpl))
...