/// <summary>
        /// Initializes a new instance of the <see cref="RegexAlternate"/> class.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        public RegexAlternate(RegexBuffer buffer)
        {
            buffer.AddLookup(this, buffer.Offset, buffer.Offset);

            // skip "|"
            buffer.MoveNext();
        }
 private void EatComment(RegexBuffer buffer)
 {
     while (buffer.Current != '\r')
     {
         buffer.MoveNext();
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="RegexAlternate"/> class.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        public RegexAlternate(RegexBuffer buffer)
        {
            buffer.AddLookup(this, buffer.Offset, buffer.Offset);

            // skip "|"
            buffer.MoveNext();
        }
 public RegexQuantifier(RegexBuffer buffer)
 {
     int startLocation = buffer.Offset;
     buffer.MoveNext();
     Match match = new Regex(@"(?<n>\d+)(?<Comma>,?)(?<m>\d*)\}").Match(buffer.String);
     if (match.Success)
     {
         if (match.Groups["m"].Length != 0)
         {
             this.description = string.Format("At least {0}, but not more than {1} times", match.Groups["n"], match.Groups["m"]);
         }
         else if (match.Groups["Comma"].Length != 0)
         {
             this.description = string.Format("At least {0} times", match.Groups["n"]);
         }
         else
         {
             this.description = string.Format("Exactly {0} times", match.Groups["n"]);
         }
         buffer.Offset += match.Groups[0].Length;
         if (!buffer.AtEnd && (buffer.Current == '?'))
         {
             this.description = this.description + " (non-greedy)";
             buffer.MoveNext();
         }
     }
     else
     {
         this.description = "missing '}' in quantifier";
     }
     buffer.AddLookup(this, startLocation, buffer.Offset - 1);
 }
 public RegexConditional(RegexBuffer buffer)
 {
     this.startLocation = buffer.Offset;
     this.expression = new RegexExpression(buffer);
     this.CheckClosingParen(buffer);
     this.yesNo = new RegexExpression(buffer);
     this.CheckClosingParen(buffer);
     buffer.AddLookup(this, this.startLocation, buffer.Offset - 1);
 }
        private string Analyze()
        {
            RegexBuffer buffer = new RegexBuffer(Pattern)
            {
                RegexOptions = Options
            };

            try
            {
                return(new RegexExpression(buffer).ToString(0));
            }
            catch (Exception ex)
            {
                return(string.Format("An error occurred while analyzing the pattern: \"{0}\".", ex.Message));
            }
        }
 private void CheckClosingParen(RegexBuffer buffer)
 {
     char current = ' ';
     try
     {
         current = buffer.Current;
     }
     catch (Exception exception)
     {
         buffer.ErrorLocation = this.startLocation;
         buffer.ErrorLength = 1;
         throw new Exception(string.Format("Missing closing ')' in capture", new object[0]), exception);
     }
     if (current != ')')
     {
         throw new Exception(string.Format("Unterminated closure at offset {0}", buffer.Offset));
     }
     buffer.Offset++;
 }
 public RegexCapture(RegexBuffer buffer)
 {
     this.startLocation = buffer.Offset;
     buffer.MoveNext();
     buffer.ClearInSeries();
     if (buffer.Current == '?')
     {
         bool flag = this.CheckNamed(buffer);
         if (!flag)
         {
             flag = this.CheckBalancedGroup(buffer);
         }
         if (!flag)
         {
             flag = this.CheckNonCapturing(buffer);
         }
         if (!flag)
         {
             flag = this.CheckOptions(buffer);
         }
         if (!flag)
         {
             flag = this.CheckLookahead(buffer);
         }
         if (!flag)
         {
             flag = this.CheckNonBacktracking(buffer);
         }
         if (!flag)
         {
             flag = this.CheckConditional(buffer);
         }
     }
     else if (!this.HandlePlainOldCapture(buffer))
     {
         throw new Exception(string.Format("Unrecognized capture: {0}", buffer.String));
     }
     buffer.AddLookup(this, this.startLocation, buffer.Offset - 1);
 }
 public RegexCharClass(RegexBuffer buffer)
 {
     int startLocation = buffer.Offset;
     buffer.MoveNext();
     Match match = new Regex(@"(?<Negated>\^?)(?<Class>.+?)\]").Match(buffer.String);
     if (match.Success)
     {
         if (match.Groups["Negated"].ToString() == "^")
         {
             this.description = string.Format("Any character not in \"{0}\"", match.Groups["Class"]);
         }
         else
         {
             this.description = string.Format("Any character in \"{0}\"", match.Groups["Class"]);
         }
         buffer.Offset += match.Groups[0].Length;
     }
     else
     {
         this.description = "missing ']' in character class";
     }
     buffer.AddLookup(this, startLocation, buffer.Offset - 1);
 }
 private bool CheckBalancedGroup(RegexBuffer buffer)
 {
     Match match = new Regex("\r\n\t\t\t\t        ^                         # anchor to start of string\r\n\t\t\t\t\t\t\\?[\\<|']                  # ?< or ?'\r\n\t\t\t\t\t\t(?<Name1>[a-zA-Z]+?)       # Capture name1\r\n\t\t\t\t\t\t-\r\n\t\t\t\t\t\t(?<Name2>[a-zA-Z]+?)       # Capture name2\r\n\t\t\t\t\t\t[\\>|']                    # ?> or ?'\r\n\t\t\t\t\t\t(?<Rest>.+)               # The rest of the expression\r\n\t\t\t\t\t\t", RegexOptions.IgnorePatternWhitespace).Match(buffer.String);
     if (match.Success)
     {
         this.description = string.Format("Balancing Group <{0}>-<{1}>", match.Groups["Name1"], match.Groups["Name2"]);
         buffer.Offset += match.Groups["Rest"].Index;
         this.expression = new RegexExpression(buffer);
         this.CheckClosingParen(buffer);
         return true;
     }
     return false;
 }
 private bool HandlePlainOldCapture(RegexBuffer buffer)
 {
     if (buffer.ExplicitCapture)
     {
         this.description = string.Format("Non-capturing Group", new object[0]);
     }
     this.expression = new RegexExpression(buffer);
     this.CheckClosingParen(buffer);
     return true;
 }
 private bool CheckOptions(RegexBuffer buffer)
 {
     Match match = new Regex("\r\n\t\t\t\t        ^                         # anchor to start of string\r\n\t\t\t\t\t\t\\?(?<Options>[imnsx-]+):\r\n\t\t\t\t\t\t", RegexOptions.IgnorePatternWhitespace).Match(buffer.String);
     if (match.Success)
     {
         string text = match.Groups["Options"].Value;
         this.description = string.Format("Set options to {0}", optionNames[text]);
         this.expression = null;
         buffer.Offset += match.Groups[0].Length;
         return true;
     }
     return false;
 }
 private bool CheckNonCapturing(RegexBuffer buffer)
 {
     Match match = new Regex("\r\n\t\t\t\t        ^                         # anchor to start of string\r\n\t\t\t\t\t\t\\?:\r\n\t\t\t\t\t\t(?<Rest>.+)             # The rest of the expression\r\n\t\t\t\t\t\t", RegexOptions.IgnorePatternWhitespace).Match(buffer.String);
     if (match.Success)
     {
         this.description = string.Format("Non-capturing Group", new object[0]);
         buffer.Offset += match.Groups["Rest"].Index;
         this.expression = new RegexExpression(buffer);
         this.CheckClosingParen(buffer);
         return true;
     }
     return false;
 }
 private bool CheckNamed(RegexBuffer buffer)
 {
     Match match = new Regex("\r\n\t\t\t\t        ^                         # anchor to start of string\r\n\t\t\t\t\t\t\\?(\\<|')                  # ?< or ?'\r\n\t\t\t\t\t\t(?<Name>[a-zA-Z0-9]+?)    # Capture name\r\n\t\t\t\t\t\t(\\>|')                    # ?> or ?'\r\n\t\t\t\t\t\t(?<Rest>.+)               # The rest of the string\r\n\t\t\t\t\t\t", RegexOptions.IgnorePatternWhitespace).Match(buffer.String);
     if (match.Success)
     {
         this.description = string.Format("Capture to <{0}>", match.Groups["Name"]);
         buffer.Offset += match.Groups["Rest"].Index;
         this.expression = new RegexExpression(buffer);
         this.CheckClosingParen(buffer);
         return true;
     }
     return false;
 }
        private bool CheckLookahead(RegexBuffer buffer)
        {
            Match match = new Regex("\r\n\t\t\t\t        ^                         # anchor to start of string\r\n\t\t\t\t\t\t\\?\r\n\t\t\t\t\t\t(?<Assertion><=|<!|=|!)   # assertion char\r\n\t\t\t\t\t\t(?<Rest>.+)               # The rest of the expression\r\n\t\t\t\t\t\t", RegexOptions.IgnorePatternWhitespace).Match(buffer.String);
            if (!match.Success)
            {
                return false;
            }
            switch (match.Groups["Assertion"].Value)
            {
                case "=":
                    this.description = "zero-width positive lookahead";
                    break;

                case "!":
                    this.description = "zero-width negative lookahead";
                    break;

                case "<=":
                    this.description = "zero-width positive lookbehind";
                    break;

                case "<!":
                    this.description = "zero-width negative lookbehind";
                    break;
            }
            buffer.Offset += match.Groups["Rest"].Index;
            this.expression = new RegexExpression(buffer);
            this.CheckClosingParen(buffer);
            return true;
        }
 private bool CheckConditional(RegexBuffer buffer)
 {
     Match match = new Regex("\r\n\t\t\t\t        ^                         # anchor to start of string\r\n\t\t\t\t\t\t\\?\\(\r\n\t\t\t\t\t\t(?<Rest>.+)             # The rest of the expression\r\n\t\t\t\t\t\t", RegexOptions.IgnorePatternWhitespace).Match(buffer.String);
     if (match.Success)
     {
         this.description = string.Format("Conditional Subexpression", new object[0]);
         buffer.Offset += match.Groups["Rest"].Index;
         this.expression = new RegexConditional(buffer);
         return true;
     }
     return false;
 }
 public RegexExpression(RegexBuffer buffer)
 {
     this.Parse(buffer);
 }
 public static string Interpret(string regex)
 {
     RegexBuffer buffer = new RegexBuffer(regex);
     RegexExpression expression = new RegexExpression(buffer);
     return expression.ToString(0);
 }
        private void Parse(RegexBuffer buffer)
        {
            while (!buffer.AtEnd)
            {
                if (buffer.IgnorePatternWhitespace && (((buffer.Current == ' ') || (buffer.Current == '\r')) || ((buffer.Current == '\n') || (buffer.Current == '\t'))))
                {
                    buffer.MoveNext();
                }
                else
                {
                    switch (buffer.Current)
                    {
                        case '(':
                        {
                            this.items.Add(new RegexCapture(buffer));
                            continue;
                        }
                        case ')':
                            return;

                        case '#':
                        {
                            if (buffer.IgnorePatternWhitespace)
                            {
                                this.EatComment(buffer);
                            }
                            else
                            {
                                this.items.Add(new RegexCharacter(buffer));
                            }
                            continue;
                        }
                        case '[':
                        {
                            this.items.Add(new TeamAgile.RegexKit.Common.RegexParser.RegexCharClass(buffer));
                            continue;
                        }
                        case '\\':
                        {
                            this.items.Add(new RegexCharacter(buffer));
                            continue;
                        }
                        case '{':
                        {
                            this.items.Add(new RegexQuantifier(buffer));
                            continue;
                        }
                        case '|':
                        {
                            this.items.Add(new RegexAlternate(buffer));
                            continue;
                        }
                    }
                    this.items.Add(new RegexCharacter(buffer));
                }
            }
        }
        public RegexCharacter(RegexBuffer buffer)
        {
            int startLocation = buffer.Offset;
            bool flag = false;
            switch (buffer.Current)
            {
                case ' ':
                    this.character = "' ' (space)";
                    buffer.MoveNext();
                    break;

                case '$':
                    this.character = "$ (anchor to end of string)";
                    buffer.MoveNext();
                    break;

                case '*':
                    this.character = "* (zero or more times)";
                    buffer.MoveNext();
                    this.special = true;
                    flag = true;
                    break;

                case '+':
                    this.character = "+ (one or more times)";
                    buffer.MoveNext();
                    this.special = true;
                    flag = true;
                    break;

                case '.':
                    this.character = ". (any character)";
                    buffer.MoveNext();
                    this.special = true;
                    break;

                case '?':
                    this.character = "? (zero or one time)";
                    buffer.MoveNext();
                    this.special = true;
                    flag = true;
                    break;

                case '\\':
                    this.DecodeEscape(buffer);
                    break;

                case '^':
                    this.character = "^ (anchor to start of string)";
                    buffer.MoveNext();
                    break;

                default:
                    this.character = buffer.Current.ToString();
                    buffer.MoveNext();
                    this.special = false;
                    break;
            }
            if ((flag && !buffer.AtEnd) && (buffer.Current == '?'))
            {
                this.character = this.character + " (non-greedy)";
                buffer.MoveNext();
            }
            buffer.AddLookup(this, startLocation, buffer.Offset - 1, this.character.Length == 1);
        }
        private void DecodeEscape(RegexBuffer buffer)
        {
            buffer.MoveNext();
            this.character = (string) escaped[buffer.Current];
            if (this.character == null)
            {
                if (!this.CheckBackReference(buffer))
                {
                    switch (buffer.Current)
                    {
                        case 'u':
                        {
                            buffer.MoveNext();
                            string text = buffer.String.Substring(0, 4);
                            this.character = "Unicode " + text;
                            buffer.Offset += 4;
                            return;
                        }
                        case 'x':
                        {
                            buffer.MoveNext();
                            string text2 = buffer.String.Substring(0, 2);
                            this.character = "Hex " + text2;
                            buffer.Offset += 2;
                            return;
                        }
                        case ' ':
                            this.character = "' ' (space)";
                            this.special = false;
                            buffer.MoveNext();
                            return;

                        case 'c':
                            buffer.MoveNext();
                            this.character = "CTRL-" + buffer.Current;
                            buffer.MoveNext();
                            return;
                    }
                    this.character = new string(buffer.Current, 1);
                    this.special = false;
                    buffer.MoveNext();
                }
            }
            else
            {
                this.special = true;
                buffer.MoveNext();
            }
        }
 private bool CheckBackReference(RegexBuffer buffer)
 {
     Match match = new Regex("\r\n\t\t\t\t\t\tk\\<(?<Name>.+?)\\>\r\n\t\t\t\t\t\t", RegexOptions.IgnorePatternWhitespace).Match(buffer.String);
     if (match.Success)
     {
         this.special = true;
         this.character = string.Format("Backreference to match: {0}", match.Groups["Name"]);
         buffer.Offset += match.Groups[0].Length;
         return true;
     }
     return false;
 }