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); } }