Пример #1
0
        public ParsedMatch <T>?Match(StringPart stringPart)
        {
            var index = stringPart.Target.IndexOf(_needle, stringPart.StartIndex, stringPart.Length, _comparison);

            if (index >= 0)
            {
                var stringPartShrunk = stringPart.Shrink(index, _needle.Length);
                return(new ParsedMatch <T>(stringPartShrunk, _transform(stringPartShrunk)));
            }

            return(null);
        }
Пример #2
0
        public ParsedMatch <T>?Match(StringPart stringPart)
        {
            var match = _regex.Match(stringPart.Target, stringPart.StartIndex, stringPart.Length);

            if (!match.Success)
            {
                return(null);
            }

            // Overload regex.Match(string, int, int) doesn't take the whole string into account,
            // it effectively functions as a match check on a substring.
            // Which is super weird because regex.Match(string, int) takes the whole input in context.
            // So in order to properly account for ^/$ regex tokens, we need to make sure that
            // the expression also matches on the bigger part of the input.
            if (!_regex.IsMatch(stringPart.Target.Substring(0, stringPart.EndIndex), stringPart.StartIndex))
            {
                return(null);
            }

            var stringPartMatch = stringPart.Slice(match.Index, match.Length);

            return(new ParsedMatch <T>(stringPartMatch, _transform(stringPartMatch, match)));
        }
Пример #3
0
 public static StringPart Shrink(this StringPart stringPart, int newStartIndex, int newLength) =>
 new StringPart(stringPart.Target, newStartIndex, newLength);
Пример #4
0
        public static IEnumerable <ParsedMatch <T> > MatchAll <T>(this IMatcher <T> matcher, StringPart stringPart,
                                                                  Func <StringPart, T> fallbackTransform)
        {
            // Loop through segments divided by individual matches
            var currentIndex = stringPart.StartIndex;

            while (currentIndex < stringPart.EndIndex)
            {
                // Find a match within this segment
                var match = matcher.Match(stringPart.Shrink(currentIndex, stringPart.EndIndex - currentIndex));

                // If there's no match - break
                if (match == null)
                {
                    break;
                }

                // If this match doesn't start immediately at current index - transform and yield fallback first
                if (match.StringPart.StartIndex > currentIndex)
                {
                    var fallbackPart = stringPart.Shrink(currentIndex, match.StringPart.StartIndex - currentIndex);
                    yield return(new ParsedMatch <T>(fallbackPart, fallbackTransform(fallbackPart)));
                }

                // Yield match
                yield return(match);

                // Shift current index to the end of the match
                currentIndex = match.StringPart.StartIndex + match.StringPart.Length;
            }

            // If EOL wasn't reached - transform and yield remaining part as fallback
            if (currentIndex < stringPart.EndIndex)
            {
                var fallbackPart = stringPart.Shrink(currentIndex);
                yield return(new ParsedMatch <T>(fallbackPart, fallbackTransform(fallbackPart)));
            }
        }
Пример #5
0
 public static StringPart Shrink(this StringPart stringPart, Capture capture) =>
 stringPart.Shrink(capture.Index, capture.Length);
Пример #6
0
 public static StringPart Shrink(this StringPart stringPart, int newStartIndex) =>
 stringPart.Shrink(newStartIndex, stringPart.EndIndex - newStartIndex);