Exemplo n.º 1
0
        public override string Execute(string input, TextWriter output)
        {
            Matches    = new List <MatchContext>();
            Separators = new List <MatchContext>();

            // We need to restore this if InputAsRegex is used.
            var tempRegexSources = RegexSources.ToList();

            if (Config.InputAsRegex)
            {
                // Swap input with first regex. There should be only one regex anyway.
                RegexSources[0] = input;
                input           = tempRegexSources[0];
            }

            switch (Config.Anchoring)
            {
            case Anchoring.String:
                RegexSources = RegexSources.ConvertAll(s => WrapRegex(@"\A", s, @"\z"));
                break;

            case Anchoring.Line:
                RegexSources = RegexSources.ConvertAll(s => WrapRegex(@"(?m:^)", s, @"(?m:$)"));
                break;
            }

            Regices = RegexSources.ConvertAll(source => new Regex(source, Config.RegexOptions));

            FindAllMatches(input);

            LimitMatches();

            if (Config.RegexOptions.HasFlag(RegexOptions.RightToLeft))
            {
                Matches.Reverse();
            }

            FillSeparators(input);

            if (Config.InvertMatches)
            {
                InvertMatches(input);
            }


            // Apply the corresponding substitution to each match.
            for (int i = 0; i < Matches.Count; ++i)
            {
                Matches[i].Replacement = Matches[i].Replacer.Process(input, Matches, Separators, i);
            }

            string result = Process(input, output);

            History.RegisterResult(HistoryIndex, result);

            // Restore the regex sources, in case we're using InputAsRegex
            RegexSources = tempRegexSources;

            return(result);
        }
Exemplo n.º 2
0
        // Returns a pair of match and the corresponding substitution string.
        private MatchContext GetMatch(string input, int startPos, int length = -1)
        {
            if (Regices.Count > 1 && Config.Greedy)
            {
                // Try all matches, pick the one with the earliest match position.

                List <Regex> patterns;

                if (length < 0)
                {
                    patterns = Regices;
                }
                else
                {
                    if (!Config.RegexOptions.HasFlag(RegexOptions.RightToLeft))
                    {
                        patterns = RegexSources.ConvertAll(s => new Regex(WrapRegex(
                                                                              String.Format("\\G(?=(?s:.{{{0}}}(?<_suffix>.*)))", length),
                                                                              s,
                                                                              @"(?=\k<_suffix>(?<-_suffix>)\z)"
                                                                              ), Config.RegexOptions));
                    }
                    else
                    {
                        patterns = RegexSources.ConvertAll(s => new Regex(WrapRegex(
                                                                              @"(?<=\A(?<-_suffix>)\k<_suffix>)",
                                                                              s,
                                                                              String.Format("(?<=(?s:(?<_suffix>.*).{{{0}}}))\\G", length)
                                                                              ), Config.RegexOptions));
                    }
                }

                var matches = new List <MatchContext>();


                for (int i = 0; i < patterns.Count; ++i)
                {
                    matches.Add(new MatchContext(
                                    patterns[i].Match(input, startPos),
                                    patterns[i],
                                    Replacers[i]
                                    ));
                }

                // For RTL matching, we have to pick the right-most match.
                if (!Config.RegexOptions.HasFlag(RegexOptions.RightToLeft))
                {
                    return(matches.Aggregate((curMin, m) =>
                                             (!curMin.Match.Success || m.Match.Success && m.Match.Index < curMin.Match.Index) ? m : curMin
                                             ));
                }
                else
                {
                    return(matches.Aggregate((curMin, m) =>
                                             (!curMin.Match.Success || m.Match.Success && m.Match.Index + m.Match.Length > curMin.Match.Index + curMin.Match.Length) ? m : curMin
                                             ));
                }
            }
            else
            {
                // Cycle through patterns

                Replacer replacer = Replacers[PatternIndex];

                if (length < 0)
                {
                    // No length constraint, use regular pattern
                    Regex pattern = Regices[PatternIndex];

                    Match m = pattern.Match(input, startPos);

                    if (m.Success)
                    {
                        ++PatternIndex;
                        PatternIndex %= Regices.Count;
                    }

                    return(new MatchContext(m, pattern, replacer));
                }
                else
                {
                    // Length is constrained, create length-specific pattern.
                    // This also constrains the starting position of the match
                    // exactly instead of giving a lower bound.
                    string patternString = RegexSources[PatternIndex];

                    // TODO: Compile the pattern first to find a guaranteed unused group name.
                    // However, this technique still messes with group numbers of explicitly
                    // named groups.
                    if (!Config.RegexOptions.HasFlag(RegexOptions.RightToLeft))
                    {
                        patternString = WrapRegex(
                            String.Format("\\G(?=(?s:.{{{0}}}(?<_suffix>.*)))", length),
                            patternString,
                            @"(?=\k<_suffix>(?<-_suffix>)\z)"
                            );
                    }
                    else
                    {
                        patternString = WrapRegex(
                            @"(?<=\A(?<-_suffix>)\k<_suffix>)",
                            patternString,
                            String.Format("(?<=(?s:(?<_suffix>.*).{{{0}}}))\\G", length)
                            );
                    }

                    Regex pattern = new Regex(patternString, Config.RegexOptions);

                    Match m = pattern.Match(input, startPos);

                    if (m.Success)
                    {
                        ++PatternIndex;
                        PatternIndex %= Regices.Count;
                    }

                    return(new MatchContext(m, pattern, replacer));
                }
            }
        }