Пример #1
0
        /// <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);
        }