Exemple #1
0
        public IMatch Clone()
        {
            var result = new CharSet()
            {
                InverseSet = InverseSet
            };

            result.AddRange(Chars);
            result.Repeat.Set(Repeat);
            return(result);
        }
Exemple #2
0
        public static PatternList Parse(string pattern)
        {
            var stack = new Stack <PatternList>();

            stack.Push(new PatternList()
            {
                Patterns = { new Pattern() }
            });

            var        last = "";
            Repetition repeat;
            var        inCharSet = false;

            foreach (var token in Tokenizer(pattern))
            {
                if (inCharSet)
                {
                    if (token.Value == "]" && token.IsOperator)
                    {
                        inCharSet = false;
                    }
                    else
                    {
                        var set = new CharSet();
                        for (var i = 0; i < token.Value.Length; i++)
                        {
                            if (i < token.Value.Length - 2 && token.Value[i + 1] == '-')
                            {
                                set.AddRange(token.Value[i], token.Value[i + 2]);
                                i += 2;
                            }
                            else
                            {
                                set.Add(token.Value[i]);
                            }
                        }
                        set.InverseSet = last == "[^";
                        stack.Peek().Patterns.Last().Matches.Add(set);
                    }
                }
                else if (token.IsOperator)
                {
                    switch (token.Value)
                    {
                    case "^":
                    case "$":
                    case @"\A":
                    case @"\b":
                    case @"\B":
                    case @"\G":
                    case @"\Z":
                    case @"\z":
                        stack.Peek().Patterns.Last().Matches.Add(new Anchor(token.Value[token.Value.Length - 1]));
                        break;

                    case "(":
                        var capture = new Capture();
                        capture.Options.Patterns.Add(new Pattern());
                        stack.Peek().Patterns.Last().Matches.Add(capture);
                        stack.Push(capture.Options);
                        break;

                    case ")":
                        stack.Pop();
                        break;

                    case "|":
                        stack.Peek().Patterns.Add(new Pattern());
                        break;

                    case "{":
                    case "}":
                        // Do nothing
                        break;

                    case "[":
                    case "[^":
                        inCharSet = true;
                        break;

                    case ".":
                    case @"\d":
                    case @"\D":
                    case @"\s":
                    case @"\S":
                    case @"\w":
                    case @"\W":
                        stack.Peek().Patterns.Last().Matches.Add(new CharSet(token.Value[token.Value.Length - 1]));
                        break;

                    case "*":
                    case "*?":
                        repeat          = stack.Peek().Patterns.Last().Matches.Last().Repeat;
                        repeat.MinCount = 0;
                        repeat.MaxCount = int.MaxValue;
                        repeat.Greedy   = token.Value.Length == 1;
                        break;

                    case "+":
                    case "+?":
                        repeat          = stack.Peek().Patterns.Last().Matches.Last().Repeat;
                        repeat.MinCount = 1;
                        repeat.MaxCount = int.MaxValue;
                        repeat.Greedy   = token.Value.Length == 1;
                        break;

                    case "?":
                        repeat = stack.Peek().Patterns.Last().Matches.Last().Repeat;
                        if (last == "}")
                        {
                            repeat.Greedy = false;
                        }
                        else
                        {
                            repeat.MinCount = 0;
                            repeat.MaxCount = 1;
                            repeat.Greedy   = true;
                        }
                        break;

                    case "??":
                        repeat          = stack.Peek().Patterns.Last().Matches.Last().Repeat;
                        repeat.MinCount = 0;
                        repeat.MaxCount = 1;
                        repeat.Greedy   = false;
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    if (last == "{")
                    {
                        var times = token.Value.Split(',').ToArray();
                        repeat          = stack.Peek().Patterns.Last().Matches.Last().Repeat;
                        repeat.MinCount = int.Parse(times[0]);
                        if (times.Length == 1)
                        {
                            repeat.MaxCount = repeat.MinCount;
                        }
                        else
                        {
                            repeat.MaxCount = string.IsNullOrEmpty(times[1]) ? int.MaxValue : int.Parse(times[1]);
                        }
                    }
                    else
                    {
                        stack.Peek().Patterns.Last().Matches.Add(new StringMatch(token.Value));
                    }
                }
                last = token.Value;
            }

            if (stack.Count != 1)
            {
                throw new InvalidOperationException();
            }
            var result = stack.Pop();

            result.Visit(Simplify);
            return(result);
        }
Exemple #3
0
        public virtual PatternList Parse(string str)
        {
            _pat      = new Pattern();
            _strMatch = new StringMatch();
            Anchor endAnchor = null;

            if (string.IsNullOrEmpty(str))
            {
                return(new PatternList());
            }

            if (str[0] == this.Pattern_Anything)
            {
                str = str.TrimStart(this.Pattern_Anything);
            }
            else
            {
                _pat.Matches.Add(new Anchor()
                {
                    Type = AnchorType.Start_Absolute
                });
            }
            if (!string.IsNullOrEmpty(str) && str[str.Length - 1] == this.Pattern_Anything)
            {
                str = str.TrimEnd(this.Pattern_Anything);
            }
            else
            {
                endAnchor = new Anchor()
                {
                    Type = AnchorType.End_Absolute
                };
            }

            var  i       = 0;
            bool inRange = false;

            while (i < str.Length)
            {
                if (inRange)
                {
                    if (str[i] == ']')
                    {
                        inRange = false;
                        _pat.Matches.Add(_set);
                        _set = null;
                    }
                    else if (_set.Chars.Count > 0 && str[i] == this.Pattern_SetRange && (i + 1) < str.Length && str[i + 1] != ']')
                    {
                        _set.AddRange((char)(_set.Chars.Last() + 1), str[i + 1]);
                        i++;
                    }
                    else
                    {
                        _set.Chars.Add(str[i]);
                    }
                }
                else if (str[i] == this.Pattern_Anything)
                {
                    FinishStringMatch();
                    _set = new CharSet('.');
                    _set.Repeat.MinCount = 0;
                    _set.Repeat.MaxCount = int.MaxValue;
                    _pat.Matches.Add(_set);
                    _set = null;
                }
                else if (str[i] == this.Pattern_SingleChar)
                {
                    FinishStringMatch();
                    _set = new CharSet('.');
                    _set.Repeat.MinCount = 1;
                    _set.Repeat.MaxCount = 1;
                    _pat.Matches.Add(_set);
                    _set = null;
                }
                else if (str[i] == this.Pattern_SingleDigit)
                {
                    FinishStringMatch();
                    _set = new CharSet('d');
                    _set.Repeat.MinCount = 1;
                    _set.Repeat.MaxCount = 1;
                    _pat.Matches.Add(_set);
                    _set = null;
                }
                else if (str[i] == '[' && !inRange && AllowCharSet)
                {
                    FinishStringMatch();
                    inRange = true;
                    _set    = new CharSet();
                    if ((i + 1) < str.Length && str[i + 1] == this.Pattern_InverseSet)
                    {
                        _set.InverseSet = true;
                        i++;
                    }
                }
                else if (str[i] == this.Pattern_Escape)
                {
                    i++;
                    _strMatch.Match.Append(str[i]);
                }
                else
                {
                    _strMatch.Match.Append(str[i]);
                }
                i++;
            }

            if (_strMatch.Match.Length > 0)
            {
                _pat.Matches.Add(_strMatch);
            }
            if (endAnchor != null)
            {
                _pat.Matches.Add(endAnchor);
            }

            var patOpts = new PatternList();

            patOpts.Patterns.Add(_pat);
            patOpts.Visit(RegexParser.Simplify);
            return(patOpts);
        }