Don't worry about the nesting, just do it iteratively as follows:
Find the first sequence in the string that has {...}
with no other braces inside. For your case, that's {Hello|Hi}
. If there are no more of that pattern, go to step 3.
Grab all the possibilities out of there and choose a random one, replacing the brace section with its value. Then go back to step 1.
There's your modified string.
Let's say you have a slightly faulty random number generator that always returns zero. Your string modification history would then be:
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.
Note particularly the transition from (c) to (d). Because we're looking for the first brace section that doesn't have braces inside it, we do the {#|++|}
before the {C{#|++|}|Java}
.
All you need to add now is the possibility that you may have {
, }
or |
within your actual text - these will need to be escaped somehow to protect them from your modification engine.
Here's a little C# program which shows this in action. It's probably not that impressively written, given my relative inexperience with the language, but it illustrates the process.
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();
}
}
}
The output is, in one example run
Hello World! C# is an awesome language.