Пример #1
0
        /// <summary>
        ///     Returns a regular expression that matches this regular expression zero or more times.</summary>
        /// <param name="greedy">
        ///     <c>true</c> to prioritise longer matches (“greedy” matching); <c>false</c> to prioritise shorter matches
        ///     (“non-greedy” matching).</param>
        protected TManyGenerex repeatInfinite <TManyGenerex, TManyGenerexMatch>(bool greedy)
            where TManyGenerex : GenerexWithResultBase <T, IEnumerable <TResult>, TManyGenerex, TManyGenerexMatch>
            where TManyGenerexMatch : GenerexMatch <T, IEnumerable <TResult> >
        {
            Func <matcher, GenerexWithResultBase <T, IEnumerable <TResult>, TManyGenerex, TManyGenerexMatch> .matcher> createRepeatInfiniteMatcher = (matcher inner) =>
            {
                GenerexWithResultBase <T, IEnumerable <TResult>, TManyGenerex, TManyGenerexMatch> .matcher newMatcher = null;
                if (greedy)
                {
                    newMatcher = (input, startIndex) => inner(input, startIndex).SelectMany(m => newMatcher(input, startIndex + m.Length)
                                                                                            .Select(m2 => new LengthAndResult <IEnumerable <TResult> >(m.Result.Concat(m2.Result), m.Length + m2.Length)))
                                 .Concat(new LengthAndResult <IEnumerable <TResult> >(Enumerable.Empty <TResult>(), 0));
                }
                else
                {
                    newMatcher = (input, startIndex) => new LengthAndResult <IEnumerable <TResult> >(Enumerable.Empty <TResult>(), 0)
                                 .Concat(inner(input, startIndex).SelectMany(m => newMatcher(input, startIndex + m.Length)
                                                                             .Select(m2 => new LengthAndResult <IEnumerable <TResult> >(m.Result.Concat(m2.Result), m.Length + m2.Length))));
                }
                return(newMatcher);
            };

            return(GenerexWithResultBase <T, IEnumerable <TResult>, TManyGenerex, TManyGenerexMatch> .Constructor(
                       createRepeatInfiniteMatcher(_forwardMatcher),
                       createRepeatInfiniteMatcher(_backwardMatcher)));
        }
Пример #2
0
 /// <summary>
 ///     Processes each match of this regular expression by running each result object through a provided selector.</summary>
 /// <typeparam name="TOtherGenerex">
 ///     Generex type to return.</typeparam>
 /// <typeparam name="TOtherGenerexMatch">
 ///     Generex match type that corresponds to <typeparamref name="TOtherGenerex"/></typeparam>
 /// <typeparam name="TOtherResult">
 ///     Type of the object returned by <paramref name="selector"/>.</typeparam>
 /// <param name="selector">
 ///     Function to process a regular expression match.</param>
 protected TOtherGenerex processRaw <TOtherGenerex, TOtherGenerexMatch, TOtherResult>(Func <TResult, TOtherResult> selector)
     where TOtherGenerex : GenerexWithResultBase <T, TOtherResult, TOtherGenerex, TOtherGenerexMatch>
     where TOtherGenerexMatch : GenerexMatch <T, TOtherResult>
 {
     return(GenerexWithResultBase <T, TOtherResult, TOtherGenerex, TOtherGenerexMatch> .Constructor(
                (input, startIndex) => _forwardMatcher(input, startIndex).Select(m => new LengthAndResult <TOtherResult>(selector(m.Result), m.Length)),
                (input, startIndex) => _backwardMatcher(input, startIndex).Select(m => new LengthAndResult <TOtherResult>(selector(m.Result), m.Length))
                ));
 }
Пример #3
0
 /// <summary>
 ///     Returns a regular expression that only matches if the subarray matched by this regular expression also matches
 ///     the specified matching function, and if so, combines the first match’s result object with the second match
 ///     using a specified selector.</summary>
 /// <typeparam name="TOtherResult">
 ///     The type of the result object associated with each match returned by <paramref name="innerMatch"/>.</typeparam>
 /// <typeparam name="TOtherGenerex">
 ///     The type of the other regular expression. (This is either <see cref="Generex{T,TResult}"/> or <see
 ///     cref="Stringerex{TResult}"/>, but with <typeparamref name="TOtherResult"/> in place of <c>TResult</c>.)</typeparam>
 /// <typeparam name="TOtherGenerexMatch">
 ///     The type of the match object for the other regular expression. (This is either <see
 ///     cref="GenerexMatch{T,TResult}"/> or <see cref="StringerexMatch{TResult}"/>, but with <typeparamref
 ///     name="TOtherResult"/> in place of <c>TResult</c>.)</typeparam>
 /// <typeparam name="TCombinedResult">
 ///     The type of the combined result object returned by <paramref name="selector"/>.</typeparam>
 /// <typeparam name="TCombinedGenerex">
 ///     The type of the new regular expression to be returned. (This is either <see cref="Generex{T,TResult}"/> or
 ///     <see cref="Stringerex{TResult}"/>, but with <typeparamref name="TCombinedResult"/> in place of
 ///     <c>TResult</c>.)</typeparam>
 /// <typeparam name="TCombinedGenerexMatch">
 ///     The type of the match object for the regular expression to be returned. (This is either <see
 ///     cref="GenerexMatch{T,TResult}"/> or <see cref="StringerexMatch{TResult}"/>, but with <typeparamref
 ///     name="TCombinedResult"/> in place of <c>TResult</c>.)</typeparam>
 /// <param name="innerMatch">
 ///     A function that runs on the subarray matched by this regular expression and returns either a match or
 ///     <c>null</c>.</param>
 /// <param name="selector">
 ///     A selector function that combines the result object associated with the match of this regular expression, and
 ///     the match returned by <paramref name="innerMatch"/>, into a new result object.</param>
 /// <remarks>
 ///     The match object passed into <paramref name="selector"/> is the same that <paramref name="innerMatch"/>
 ///     returned. Therefore, its <see cref="GenerexMatch{T}.Index"/> property refers to the index within the subarray,
 ///     not the original input sequence.</remarks>
 protected TCombinedGenerex and <TOtherResult, TOtherGenerex, TOtherGenerexMatch, TCombinedResult, TCombinedGenerex, TCombinedGenerexMatch>(Func <T[], TOtherGenerexMatch> innerMatch, Func <TResult, TOtherGenerexMatch, TCombinedResult> selector)
     where TOtherGenerex : GenerexWithResultBase <T, TOtherResult, TOtherGenerex, TOtherGenerexMatch>
     where TOtherGenerexMatch : GenerexMatch <T, TOtherResult>
     where TCombinedGenerex : GenerexWithResultBase <T, TCombinedResult, TCombinedGenerex, TCombinedGenerexMatch>
     where TCombinedGenerexMatch : GenerexMatch <T, TCombinedResult>
 {
     return(GenerexWithResultBase <T, TCombinedResult, TCombinedGenerex, TCombinedGenerexMatch> .Constructor(
                (input, startIndex) => _forwardMatcher(input, startIndex).SelectMany(m =>
     {
         var subarray = input.Subarray(startIndex, getLength(m));
         var submatch = innerMatch(subarray);
         return submatch == null ? Enumerable.Empty <LengthAndResult <TCombinedResult> >() : new[] { new LengthAndResult <TCombinedResult>(selector(m.Result, submatch), m.Length) };
     }),
                (input, startIndex) => _backwardMatcher(input, startIndex).SelectMany(m =>
     {
         var length = getLength(m);
         var subarray = input.Subarray(startIndex + length, -length);
         var submatch = innerMatch(subarray);
         return submatch == null ? Enumerable.Empty <LengthAndResult <TCombinedResult> >() : new[] { new LengthAndResult <TCombinedResult>(selector(m.Result, submatch), m.Length) };
     })
                ));
 }
Пример #4
0
        /// <summary>
        ///     Returns a regular expression that matches this regular expression any number of times within specified
        ///     boundaries.</summary>
        /// <param name="min">
        ///     Minimum number of times to match.</param>
        /// <param name="max">
        ///     Maximum number of times to match.</param>
        /// <param name="greedy">
        ///     <c>true</c> to prioritise longer matches (“greedy” matching); <c>false</c> to prioritise shorter matches
        ///     (“non-greedy” matching).</param>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     <paramref name="min"/> is negative.</exception>
        /// <exception cref="ArgumentException">
        ///     <paramref name="max"/> is smaller than <paramref name="min"/>.</exception>
        protected TManyGenerex repeatBetween <TManyGenerex, TManyGenerexMatch>(int min, int max, bool greedy)
            where TManyGenerex : GenerexWithResultBase <T, IEnumerable <TResult>, TManyGenerex, TManyGenerexMatch>
            where TManyGenerexMatch : GenerexMatch <T, IEnumerable <TResult> >
        {
            if (min < 0)
            {
                throw new ArgumentOutOfRangeException("'min' cannot be negative.", "min");
            }
            if (max < min)
            {
                throw new ArgumentException("'max' cannot be smaller than 'min'.", "max");
            }
            var rm = new repeatMatcher
            {
                Greedy               = greedy,
                MinTimes             = min,
                MaxTimes             = max,
                InnerForwardMatcher  = _forwardMatcher,
                InnerBackwardMatcher = _backwardMatcher
            };

            return(GenerexWithResultBase <T, IEnumerable <TResult>, TManyGenerex, TManyGenerexMatch> .Constructor(rm.ForwardMatcher, rm.BackwardMatcher));
        }
Пример #5
0
        /// <summary>
        ///     Returns a regular expression that matches this regular expression, followed by the specified one, and
        ///     generates a result object that combines the original two matches.</summary>
        protected TCombinedGenerex thenRaw <TOtherGenerex, TOtherGenerexMatch, TOtherResult, TCombinedGenerex, TCombinedGenerexMatch, TCombinedResult>(
            GenerexWithResultBase <T, TOtherResult, TOtherGenerex, TOtherGenerexMatch> other, Func <TResult, TOtherResult, TCombinedResult> selector)
            where TOtherGenerex : GenerexWithResultBase <T, TOtherResult, TOtherGenerex, TOtherGenerexMatch>
            where TOtherGenerexMatch : GenerexMatch <T, TOtherResult>
            where TCombinedGenerex : GenerexWithResultBase <T, TCombinedResult, TCombinedGenerex, TCombinedGenerexMatch>
            where TCombinedGenerexMatch : GenerexMatch <T, TCombinedResult>
        {
            if (other == null)
            {
                throw new ArgumentNullException("other");
            }
            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }

            return(GenerexWithResultBase <T, TCombinedResult, TCombinedGenerex, TCombinedGenerexMatch> .Constructor(
                       (input, startIndex) => _forwardMatcher(input, startIndex).SelectMany(m => other._forwardMatcher(input, startIndex + m.Length)
                                                                                            .Select(m2 => new LengthAndResult <TCombinedResult>(selector(m.Result, m2.Result), m.Length + m2.Length))),
                       (input, startIndex) => other._backwardMatcher(input, startIndex).SelectMany(m2 => _backwardMatcher(input, startIndex + m2.Length)
                                                                                                   .Select(m => new LengthAndResult <TCombinedResult>(selector(m.Result, m2.Result), m.Length + m2.Length)))
                       ));
        }