fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.IO;
  5. using System.Text;
  6.  
  7. namespace RegexGenerator
  8. {
  9. class RegexGenerator
  10. {
  11. // For simplicity's sake, we'll limit the options to to 7-bit ASCII.
  12. static char[] _allPrintableChars = null;
  13. static char[] AllPrintableChars
  14. {
  15. get
  16. {
  17. if (_allPrintableChars == null)
  18. _allPrintableChars = Enumerable.Range(32, 127 - 32).Select(i => (char)i).ToArray();
  19. return _allPrintableChars;
  20. }
  21. }
  22.  
  23. struct Path
  24. {
  25. public char Value;
  26. public List<Path> NextState;
  27.  
  28. public Path(char value, List<Path> nextState)
  29. {
  30. Value = value;
  31. NextState = nextState;
  32. }
  33. }
  34.  
  35. static Random Rand = new Random(); // random generator
  36.  
  37. List<Path> startState;
  38.  
  39. RegexGenerator(string regex)
  40. {
  41. startState = new List<Path>();
  42.  
  43. var currentState = startState;
  44.  
  45. using (StringReader sr = new StringReader(regex))
  46. {
  47. char[] pathValues;
  48. while (GetNextValueSet(sr, out pathValues))
  49. {
  50. var newState = new List<Path>();
  51.  
  52. int nextChar = sr.Peek();
  53. if (nextChar == '*')
  54. {
  55. sr.Read();
  56. currentState.Add(new Path('\0', newState));
  57. currentState.AddRange(pathValues.Select(c => new Path(c, currentState)));
  58. }
  59. else
  60. {
  61. currentState.AddRange(pathValues.Select(c => new Path(c, newState)));
  62.  
  63. if (nextChar == '+')
  64. {
  65. sr.Read();
  66. currentState = newState;
  67. currentState.AddRange(pathValues.Select(c => new Path(c, currentState)));
  68.  
  69. newState = new List<Path>();
  70. currentState.Add(new Path('\0', newState));
  71. }
  72. }
  73. currentState = newState;
  74. }
  75. }
  76. }
  77.  
  78. bool GetNextValueSet(StringReader sr, out char[] pathValues)
  79. {
  80. int c = sr.Read();
  81. switch (c)
  82. {
  83. case -1: pathValues = null; return false;
  84.  
  85. default: pathValues = new char[] { (char)c }; return true;
  86.  
  87. case '\\':
  88. c = AssertRead(sr, "Pattern ends in trailing backslash.");
  89. goto default;
  90.  
  91. case '*':
  92. case '+':
  93. throw new Exception("Syntax error: Invalid character ('" + (char)c + "')");
  94.  
  95. case '.':
  96. pathValues = AllPrintableChars;
  97. return true;
  98.  
  99. case '[':
  100. List<char> charlist = new List<char>();
  101. while ((c = AssertRead(sr, "Missing close bracket.")) != ']')
  102. {
  103. if (c == '\\')
  104. c = AssertRead(sr, "Pattern ends in trailing backslash.");
  105.  
  106. int nextChar = sr.Peek();
  107. if (nextChar == -1)
  108. throw new Exception("Syntax Error: Missing close bracket.");
  109.  
  110. if (nextChar == '-') // add range
  111. {
  112. sr.Read();
  113. nextChar = sr.Read();
  114.  
  115. if (nextChar == ']')
  116. {
  117. charlist.Add((char)c);
  118. charlist.Add('-');
  119. break;
  120. }
  121. else if (nextChar == '\\')
  122. nextChar = AssertRead(sr, "Pattern ends in trailing backslash.");
  123.  
  124. if (nextChar < c)
  125. throw new Exception("Syntax Error: Range out of order.");
  126.  
  127. charlist.AddRange(Enumerable.Range(c, nextChar - c + 1).Select(i => (char)i));
  128. }
  129. else
  130. {
  131. charlist.Add((char)c);
  132. }
  133. }
  134. pathValues = charlist.Distinct().ToArray();
  135. return true;
  136. }
  137. }
  138.  
  139. int AssertRead(TextReader reader, string message)
  140. {
  141. int c = reader.Read();
  142. if (c == -1)
  143. throw new Exception("Syntax error: " + message);
  144. return c;
  145. }
  146.  
  147. string GenerateRandomPattern()
  148. {
  149. StringBuilder sb = new StringBuilder();
  150.  
  151. var currentState = startState;
  152. while (currentState.Count > 0)
  153. {
  154. Path pathToTake = currentState[Rand.Next(currentState.Count)];
  155. if (pathToTake.Value != '\0')
  156. {
  157. sb.Append(pathToTake.Value);
  158. }
  159. currentState = pathToTake.NextState;
  160. }
  161.  
  162. return sb.ToString();
  163. }
  164.  
  165. static void Main(string[] args)
  166. {
  167. try
  168. {
  169. var gen = new RegexGenerator("[A-Za-z0-9$.+!*'(){},~:;=@#%_\\-]*");
  170. Console.WriteLine(gen.GenerateRandomPattern());
  171.  
  172. gen = new RegexGenerator("ab[c-l]+jkm9*10+");
  173. Console.WriteLine(gen.GenerateRandomPattern());
  174.  
  175. gen = new RegexGenerator("iqb[beoqob-q]872+0qbq*");
  176. Console.WriteLine(gen.GenerateRandomPattern());
  177. }
  178. catch (Exception e)
  179. {
  180. Console.WriteLine(e.Message);
  181. }
  182. //Console.Read();
  183. }
  184. }
  185. }
Success #stdin #stdout 0.01s 131712KB
stdin
Standard input is empty
stdout
sJagqL7A
abjcgcjkm10
iqbp87220qb