예제 #1
0
    public static IEnumerable <ParsedMatch <T> > MatchAll <T>(this IMatcher <T> matcher,
                                                              StringPart stringPart, Func <StringPart, T> transformFallback)
    {
        // Loop through segments divided by individual matches
        var currentIndex = stringPart.StartIndex;

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

            // If there's no match - break
            if (match is 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.Slice(currentIndex, match.StringPart.StartIndex - currentIndex);
                yield return(new ParsedMatch <T>(fallbackPart, transformFallback(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.Slice(currentIndex);
            yield return(new ParsedMatch <T>(fallbackPart, transformFallback(fallbackPart)));
        }
    }
예제 #2
0
    public ParsedMatch <T>?TryMatch(StringPart stringPart)
    {
        var index = stringPart.Target.IndexOf(_needle, stringPart.StartIndex, stringPart.Length, _comparison);

        if (index < 0)
        {
            return(null);
        }

        var stringPartMatch = stringPart.Slice(index, _needle.Length);
        var value           = _transform(stringPartMatch);

        return(value is not null
            ? new ParsedMatch <T>(stringPartMatch, value)
            : null);
    }