ネストについて心配する必要はありません。次のように繰り返し実行してください。
{...}
中括弧が入っていない文字列の最初のシーケンスを見つけます。あなたの場合、それは{Hello|Hi}
です。そのパターンがこれ以上ない場合は、ステップ3に進みます。
そこからすべての可能性をつかみ、ランダムなものを選択して、ブレースセクションをその値に置き換えます。次に、手順1に戻ります。
変更された文字列があります。
常にゼロを返す、わずかに障害のある乱数ジェネレーターがあるとします。文字列の変更履歴は次のようになります。
a / {Hello | Hi} {World | People}!{C {#| ++ |}|Java}は{素晴らしい|驚くべき}言語です。
b /こんにちは{世界|人}!{C {#| ++ |}|Java}は{素晴らしい|驚くべき}言語です。
c / Hello World!{C {#| ++ |}|Java}は{素晴らしい|驚くべき}言語です。
d / Hello World!{C#|Java}は{awesome|amazing}言語です。
e / Hello World!C#は{素晴らしい|素晴らしい}言語です。
f / Hello World!C#は素晴らしい言語です。
特に(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();
}
}
}
出力は、一例では実行されます
「こんにちは世界」C#は素晴らしい言語です。