/// <summary> /// Given a regular expression, attempt to generate a string that would match it. This is a rather /// simple implementation, so don't be shocked if it blows up on you in a spectacular fashion. It does /// not handle ., *, unbound ranges such as {1,}, extensions such as (?=), character classes, some /// abbreviations for characters classes, and nested parantheses. I told you it was simple. :) It's /// also probably dog-slow, so you shouldn't use it. It will take a reg ex like this: /// "^[A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}$" /// and generate a string like this: "U3V 3TP" /// </summary> /// <param name="reg"></param> /// <returns></returns> public static string Regexify(this string reg) { // Trim slashes: reg = reg.Trim('/'); // Ditch the anchors reg = Regex.Replace(reg, @"{^\/?\^?}", string.Empty, RegexOptions.Compiled); reg = Regex.Replace(reg, @"{\$?\/?$}", string.Empty, RegexOptions.Compiled); // All {2} become {2,2} reg = Regex.Replace(reg, @"\{(\d+)\}", "{$1,$1}", RegexOptions.Compiled); // All ? become {0,1} reg = Regex.Replace(reg, @"\?", "{0,1}", RegexOptions.Compiled); // [12]{1,2} becomes [12] or [12][12] reg = reg.ExpandRanges(); // (12|34){1,2} becomes (12|34) or (12|34)(12|34) reg = Regex.Replace(reg, @"(\([^\)]+\))\{(\d+),(\d+)\}", match => { throw new NotImplementedException(); }, RegexOptions.Compiled); // A{1,2} becomes A or AA or \d{3} becomes \d\d\d reg = Regex.Replace(reg, @"(\\?.)\{(\d+),(\d+)\}", match => { var toRepeat = match.Groups[1].Value; var lowerBoundary = int.Parse(match.Groups[2].Value); var upperBoundary = int.Parse(match.Groups[3].Value); int[] intRange = new Range2 <int>(lowerBoundary, upperBoundary).AsArray(); var result = string.Concat(intRange.Sample().Times(_ => toRepeat)); return(result); }, RegexOptions.Compiled); // (this|that) becomes 'this' or 'that' reg = ExpandOr(reg); // All A-Z inside of [] become C (or X, or whatever) reg = Regex.Replace(reg, @"\[([^\]]+)\]", match => { var result = Regex.Replace(match.Value, @"(\w\-\w)", range => { var parts = Regex.Split(range.Value, "-"); var charRange = new Range2 <char>(parts[0][0], parts[1][0]); return($"{charRange.Sample()}"); }); return(result); }, RegexOptions.Compiled); // All [ABC] become B (or A or C) reg = Regex.Replace(reg, @"\[([^\]]+)\]", match => { var charRange = match.Groups[1].Value.ToCharArray(); return($"{charRange.Sample()}"); }, RegexOptions.Compiled); reg = Regex.Replace(reg, Regex.Escape(@"\d"), _ => $"{Numbers.Sample()}", RegexOptions.Compiled); reg = Regex.Replace(reg, Regex.Escape(@"\w"), _ => $"{Letters.Sample()}", RegexOptions.Compiled); return(reg); }