/// <summary>
        /// Replaces all occurrences of the regex in the string with the
        /// replacement pattern.
        ///
        /// Note that the special case of no matches is handled on its own:
        /// with no matches, the input string is returned unchanged.
        /// The right-to-left case is split out because StringBuilder
        /// doesn't handle right-to-left string building directly very well.
        /// </summary>
        public string Replace(Regex regex, string input, int count, int startat)
        {
            if (count < -1)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.CountTooSmall);
            }
            if ((uint)startat > (uint)input.Length)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startat, ExceptionResource.BeginIndexNotNegative);
            }

            if (count == 0)
            {
                return(input);
            }

            var state = (replacement : this, segments : SegmentStringBuilder.Create(), inputMemory : input.AsMemory(), prevat : 0, count);

            if (!regex.RightToLeft)
            {
                regex.Run(input, startat, ref state, (ref (RegexReplacement thisRef, SegmentStringBuilder segments, ReadOnlyMemory <char> inputMemory, int prevat, int count)state, Match match) =>
                {
                    state.segments.Add(state.inputMemory.Slice(state.prevat, match.Index - state.prevat));
                    state.prevat = match.Index + match.Length;
                    state.thisRef.ReplacementImpl(ref state.segments, match);
                    return(--state.count != 0);
                }, reuseMatchObject: true);
Exemple #2
0
        /// <summary>
        /// Replaces all occurrences of the regex in the string with the
        /// replacement evaluator.
        ///
        /// Note that the special case of no matches is handled on its own:
        /// with no matches, the input string is returned unchanged.
        /// The right-to-left case is split out because StringBuilder
        /// doesn't handle right-to-left string building directly very well.
        /// </summary>
        private static string Replace(MatchEvaluator evaluator, Regex regex, string input, int count, int startat)
        {
            if (evaluator is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.evaluator);
            }
            if (count < -1)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.CountTooSmall);
            }
            if ((uint)startat > (uint)input.Length)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startat, ExceptionResource.BeginIndexNotNegative);
            }

            if (count == 0)
            {
                return(input);
            }

            var state = (segments : SegmentStringBuilder.Create(), evaluator, prevat : 0, input, count);

            if (!regex.RightToLeft)
            {
                regex.Run(input, startat, ref state, static (ref (SegmentStringBuilder segments, MatchEvaluator evaluator, int prevat, string input, int count)state, Match match) =>
                {
                    state.segments.Add(state.input.AsMemory(state.prevat, match.Index - state.prevat));
                    state.prevat = match.Index + match.Length;
                    state.segments.Add(state.evaluator(match).AsMemory());
                    return(--state.count != 0);
                }, reuseMatchObject: false);
        private Match?GetMatch(int i)
        {
            Debug.Assert(i >= 0, "i cannot be negative.");

            if (_matches.Count > i)
            {
                return(_matches[i]);
            }

            if (_done)
            {
                return(null);
            }

            Match match;

            do
            {
                match = _regex.Run(false, _prevlen, _input, 0, _input.Length, _startat) !;
                if (!match.Success)
                {
                    _done = true;
                    return(null);
                }

                _matches.Add(match);
                _prevlen = match.Length;
                _startat = match._textpos;
            } while (_matches.Count <= i);

            return(match);
        }
Exemple #4
0
        /*
         * Returns the next match
         */
        /// <devdoc>
        ///    <para>Returns a new Match with the results for the next match, starting
        ///       at the position at which the last match ended (at the character beyond the last
        ///       matched character).</para>
        /// </devdoc>
        public Match NextMatch()
        {
            if (_regex == null)
            {
                return(this);
            }

            return(_regex.Run(false, _length, _text, _textbeg, _textend - _textbeg, _textpos));
        }
        /// <summary>
        /// Does a split. In the right-to-left case we reorder the
        /// array to be forwards.
        /// </summary>
        private static string[] Split(Regex regex, string input, int count, int startat)
        {
            if (count < 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.CountTooSmall);
            }
            if ((uint)startat > (uint)input.Length)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startat, ExceptionResource.BeginIndexNotNegative);
            }

            if (count == 1)
            {
                return(new[] { input });
            }

            count--;
            var state = (results : new List <string>(), prevat : 0, input, count);

            if (!regex.RightToLeft)
            {
                regex.Run(input, startat, ref state, (ref (List <string> results, int prevat, string input, int count)state, Match match) =>
                {
                    state.results.Add(state.input.Substring(state.prevat, match.Index - state.prevat));
                    state.prevat = match.Index + match.Length;

                    // add all matched capture groups to the list.
                    for (int i = 1; i < match.Groups.Count; i++)
                    {
                        if (match.IsMatched(i))
                        {
                            state.results.Add(match.Groups[i].ToString());
                        }
                    }

                    return(--state.count != 0);
                });
        internal Match GetMatch(int i)
        {
            if (i < 0)
            {
                return(null);
            }

            if (_matches.Count > i)
            {
                return((Match)_matches[i]);
            }

            if (_done)
            {
                return(null);
            }

            Match match;

            do
            {
                match = _regex.Run(false, _prevlen, _input, _beginning, _length, _startat);

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

                _matches.Add(match);

                _prevlen = match._length;
                _startat = match._textpos;
            } while (_matches.Count <= i);

            return(match);
        }