fork(1) download
  1. using System;
  2. using System.Text;
  3.  
  4. namespace ConsoleApplication51
  5. {
  6. class Program
  7. {
  8. static class RangeChecker
  9. {
  10. public static string BuildRegex(string matches)
  11. {
  12. string[] splits = matches.Split(',');
  13.  
  14. if (splits.Length == 0)
  15. {
  16. return "^()$";
  17. }
  18.  
  19. StringBuilder res = new StringBuilder();
  20. res.Append("^(");
  21.  
  22. foreach (string split in splits)
  23. {
  24. if (split == "*")
  25. {
  26. return "^([0-9]+)$";
  27. }
  28.  
  29. string[] subSplit = split.Split('-');
  30.  
  31. string min = subSplit[0].TrimStart('0');
  32.  
  33. if (min == string.Empty)
  34. {
  35. return null;
  36. }
  37.  
  38. if (subSplit.Length == 1)
  39. {
  40. res.Append(min);
  41. res.Append('|');
  42.  
  43. continue;
  44. }
  45. else if (subSplit.Length > 2)
  46. {
  47. return null;
  48. }
  49.  
  50. string max = subSplit[1].TrimStart('0');
  51.  
  52. if (max == string.Empty)
  53. {
  54. return null;
  55. }
  56.  
  57. if (min.Length > max.Length)
  58. {
  59. return null;
  60. }
  61.  
  62. // For 2-998 we first produce 2-9, then 10-99
  63. string tempMin = BuildRegexDifferentLength(res, min, max);
  64.  
  65. if (tempMin == null)
  66. {
  67. return null;
  68. }
  69.  
  70. // Then here 100-998
  71. BuildRegexSameLength(res, tempMin, max);
  72. }
  73.  
  74. res.Length--;
  75. res.Append(")$");
  76.  
  77. return res.ToString();
  78. }
  79.  
  80. private static bool IsOnlyDigit(string str, int start, char digit)
  81. {
  82. for (int i = start; i < str.Length; i++)
  83. {
  84. if (str[i] != digit)
  85. {
  86. return false;
  87. }
  88. }
  89.  
  90. return true;
  91. }
  92.  
  93. private static string BuildRangeDigit(char min, char max)
  94. {
  95. if (min == max)
  96. {
  97. return min.ToString();
  98. }
  99.  
  100. return "[" + min + "-" + max + "]";
  101. }
  102.  
  103. private static string BuildRegexDifferentLength(StringBuilder res, string min, string max)
  104. {
  105. string tempMin = min;
  106.  
  107. for (int i = min.Length; i < max.Length; i++)
  108. {
  109. string tempMax = new string('9', i);
  110.  
  111. BuildRegexSameLength(res, tempMin, tempMax);
  112.  
  113. tempMin = "1" + new string('0', i);
  114. }
  115.  
  116. if (tempMin.CompareTo(max) > 0)
  117. {
  118. return null;
  119. }
  120.  
  121. return tempMin;
  122. }
  123.  
  124. private static void BuildRegexSameLength(StringBuilder res, string min, string max)
  125. {
  126. // 100-100
  127. if (min == max)
  128. {
  129. res.Append(min);
  130. res.Append('|');
  131.  
  132. return;
  133. }
  134.  
  135. int commonPart = 0;
  136.  
  137. for (; commonPart < min.Length; commonPart++)
  138. {
  139. if (min[commonPart] != max[commonPart])
  140. {
  141. break;
  142. }
  143. }
  144.  
  145. RecursivelyAddRegexRange(res, min.Substring(0, commonPart), min.Substring(commonPart), max.Substring(commonPart));
  146. }
  147.  
  148. private static void RecursivelyAddRegexRange(StringBuilder res, string prefix, string min, string max)
  149. {
  150. if (min.Length == 1)
  151. {
  152. res.Append(prefix);
  153. res.Append(BuildRangeDigit(min[0], max[0]));
  154. res.Append('|');
  155.  
  156. return;
  157. }
  158.  
  159. // Check if
  160. bool only0Min = IsOnlyDigit(min, 1, '0');
  161. bool only9Max = IsOnlyDigit(max, 1, '9');
  162.  
  163. if (only0Min && only9Max)
  164. {
  165. res.Append(prefix);
  166. res.Append(BuildRangeDigit(min[0], max[0]));
  167.  
  168. for (int i = 1; i < min.Length; i++)
  169. {
  170. res.Append("[0-9]");
  171. }
  172.  
  173. res.Append('|');
  174.  
  175. return;
  176. }
  177.  
  178. string middleMin = min;
  179.  
  180. if (!only0Min)
  181. {
  182. RecursivelyAddRegexRange(res, prefix + min[0], min.Substring(1), new string('9', min.Length - 1));
  183.  
  184. if (min[0] != '9')
  185. {
  186. middleMin = (char)(min[0] + 1) + new string('0', min.Length - 1);
  187. }
  188. else
  189. {
  190. middleMin = null;
  191. }
  192. }
  193.  
  194. string middleMax = max;
  195.  
  196. if (!only9Max)
  197. {
  198. if (max[0] != '0')
  199. {
  200. middleMax = (char)(max[0] - 1) + new string('9', max.Length - 1);
  201. }
  202. else
  203. {
  204. middleMax = null;
  205. }
  206. }
  207.  
  208. if (middleMin != null && middleMax != null && middleMin[0] <= middleMax[0])
  209. {
  210. RecursivelyAddRegexRange(res, prefix + BuildRangeDigit(middleMin[0], middleMax[0]), middleMin.Substring(1), middleMax.Substring(1));
  211. }
  212.  
  213. if (!only9Max)
  214. {
  215. RecursivelyAddRegexRange(res, prefix + max[0], new string('0', max.Length - 1), max.Substring(1));
  216. }
  217. }
  218. }
  219.  
  220. static void Main(string[] args)
  221. {
  222. Action<string> printRegex = p => Console.WriteLine("{0}: {1}", p, RangeChecker.BuildRegex(p));
  223.  
  224. printRegex("*");
  225. printRegex("1");
  226. printRegex("1,*");
  227. printRegex("1,2,3,4");
  228. printRegex("1,11-88");
  229. printRegex("1,11-88,90-101");
  230. printRegex("1-11111");
  231. printRegex("75-11119");
  232. }
  233. }
  234. }
  235.  
Success #stdin #stdout 0.06s 34192KB
stdin
Standard input is empty
stdout
*: ^([0-9]+)$
1: ^(1)$
1,*: ^([0-9]+)$
1,2,3,4: ^(1|2|3|4)$
1,11-88: ^(1|1[1-9]|[2-7][0-9]|8[0-8])$
1,11-88,90-101: ^(1|1[1-9]|[2-7][0-9]|8[0-8]|9[0-9]|10[0-1])$
1-11111: ^([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|10[0-9][0-9][0-9]|110[0-9][0-9]|1110[0-9]|1111[0-1])$
75-11119: ^(7[5-9]|[8-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|10[0-9][0-9][0-9]|110[0-9][0-9]|111[0-1][0-9])$