Spintax C # ... Как я могу справиться с этим? - PullRequest
4 голосов
/ 04 ноября 2011

Spintax позволяет вращать различные слова и предложения, такие как:

{Hello|Hi} {World|People}! {C{#|++|}|Java} is an {awesome|amazing} language.

Текст между фигурными скобками будет выбираться случайным образом для формирования разных предложений.

Я могу возможноПридумайте решение самостоятельно, но проблема, с которой я столкнусь, - это вложенность.Иногда вложение может быть очень глубоким.Каково было бы возможное решение для обработки вложенности?

Я не могу собрать необходимую логику.

Ответы [ 2 ]

8 голосов
/ 04 ноября 2011

Не беспокойтесь о вложенности, просто сделайте это итеративно следующим образом:

  1. Найдите первую последовательность в строке, которая имеет {...} без других фигурных скобок внутри.Для вашего случая это {Hello|Hi}.Если этого шаблона больше нет, перейдите к шагу 3.

  2. Возьмите все возможные варианты и выберите случайную, заменив секцию фигурных скобок ее значением.Затем вернитесь к шагу 1.

  3. Вот ваша измененная строка.

Допустим, у вас есть слегка неисправный генератор случайных чисел, который всегда возвращает ноль,Ваша история изменения строки будет тогда:

a/ {Hello|Hi} {World|People}! {C{#|++|}|Java} is an {awesome|amazing} language.
b/ Hello {World|People}! {C{#|++|}|Java} is an {awesome|amazing} language.
c/ Hello World! {C{#|++|}|Java} is an {awesome|amazing} language.
d/ Hello World! {C#|Java} is an {awesome|amazing} language.
e/ Hello World! C# is an {awesome|amazing} language.
f/ Hello World! C# is an awesome language.

Обратите особое внимание на переход от (c) к (d).Поскольку мы ищем первую секцию фигурных скобок, в которой нет фигурных скобок внутри, мы делаем {#|++|} перед {C{#|++|}|Java}.

Все, что вам нужно добавить сейчас, этовероятность того, что у вас может быть {, } или | в вашем фактическом тексте - их нужно как-то экранировать, чтобы защитить их от вашего механизма модификации.


Вот немного C #Программа, которая показывает это в действии.Это, вероятно, не так впечатляюще написано, учитывая мою относительную неопытность по отношению к языку, но оно иллюстрирует процесс.

using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static string spintax(Random rnd, string str) {
            // Loop over string until all patterns exhausted.
            string pattern = "{[^{}]*}";
            Match m = Regex.Match(str, pattern);
            while (m.Success) {
                // Get random choice and replace pattern match.
                string seg = str.Substring(m.Index + 1, m.Length - 2);
                string[] choices = seg.Split('|');
                str = str.Substring(0, m.Index) + choices[rnd.Next(choices.Length)] + str.Substring(m.Index + m.Length);
                m = Regex.Match(str, pattern);
            }

            // Return the modified string.
            return str;
        }

        static void Main(string[] args) {
            Random rnd = new Random();
            string str = "{Hello|Hi} {World|People}! {C{#|++|}|Java} is an {awesome|amazing} language.";
            Console.WriteLine(spintax(rnd, str));
            Console.ReadLine();
        }
    }
}

В одном примере выведите

Hello World! C# is an awesome language.
2 голосов
/ 04 ноября 2011

Я был бы склонен создать рекурсивный метод для обработки синтаксического анализа.Напишите метод, который принимает строку, сканирует фигурные скобки первого уровня и делает случайные выборы из вложенных опций.Затем метод вызовет сам себя с выбранной строкой параметра, прежде чем вставить его в окончательный результат.

...