using System;
using System.Text.RegularExpressions;
using System.Diagnostics;
public class Test
{
static Regex reg = new Regex(@"\{[^\{\}]*\}", RegexOptions.Compiled);
static Random
rand = new Random
((int)DateTime.
Now.
Ticks); static String[] parts;
public static void Main()
{
String text = "Oh! {{I'm|You're} here!|How are you{ doing{|, {buddy|pal|guy}}|}?}";
Console.WriteLine("Input Text: " + text);
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinRE: " + SpinRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
Stopwatch s1 = new Stopwatch();
Stopwatch s2 = new Stopwatch();
for (int i = 0; i < 100000; i++)
{
s1.Start(); SpinRE(text); s1.Stop();
s2.Start(); SpinNoRE(text); s2.Stop();
}
Console.WriteLine("\nTime elapsed over 100,000 runs of each in alternation:\n");
Console.WriteLine("SpinRE: " + String.Format("{0:00}.{1:000}", s1.Elapsed.Seconds, s1.Elapsed.Milliseconds) + "s");
Console.WriteLine("SpinNoRE: " + String.Format("{0:00}.{1:000}", s2.Elapsed.Seconds, s2.Elapsed.Milliseconds) + "s");
}
public static String SpinRE(String text)
{
while (true)
{
Match m = reg.Match(text);
if (!m.Success) break;
parts = m.Value.Substring(1, m.Value.Length-2).Split('|');
text
= text.
Substring(0, m.
Index) + parts
[rand.
Next(parts.
Length)] + text.
Substring(m.
Index + m.
Length); }
return text;
}
public static String SpinNoRE(String text)
{
int i; // stores index of current open brace.
int j; // stores index of current close brace.
int e; // stores index of earliest untouched open brace.
// helpers.
char[] curls = new char[] {'{', '}'};
// hack to prevent ArgumentOutOfRangeExceptions without having to check.
text += '~';
// index of "earliest untouched open brace" is unknown at start.
e = -1;
do
{
i = e;
e = -1;
// loop as long as an open brace is found.
while ((i = text.IndexOf('{', i+1)) != -1)
{
j = i;
// loop as long as a brace is found and it is not a close brace.
while ((j = text.IndexOfAny(curls, j+1)) != -1 && text[j] != '}')
{
// means nested spintax was found; make j (the inner open
// brace) the "new" i and continue search for close brace.
// nested spintax found; we're going to skip the current
// open brace in favor of this new one; but remember the
// index of the current open brace if it's the first such
// to be skipped; make j the "new" i; continue the search.
if (e == -1) e = i;
i = j;
}
// if close brace found, process spintax.
if (j != -1)
{
parts = text.Substring(i+1, (j-1)-(i+1-1)).Split('|');
text
= text.
Remove(i
, j
-(i
-1)).
Insert(i
, parts
[rand.
Next(parts.
Length)]); }
}
}
// loop as long as an earlier untouched open brace exists (decrement e
// before looping: the next loop begins its search at "i+1" == "e+1").
while (e-- != -1);
// undo aforementioned hack and return.
return text.Remove(text.Length-1);
}
}