/// <summary> /// Does a split. In the right-to-left case we reorder the /// array to be forwards. /// </summary> internal static string[] Split(Regex regex, string input, int count, int startat) { if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), SR.CountTooSmall); } if (startat < 0 || startat > input.Length) { throw new ArgumentOutOfRangeException(nameof(startat), SR.BeginIndexNotNegative); } string[] result; if (count == 1) { result = new string[1]; result[0] = input; return(result); } count -= 1; Match match = regex.Match(input, startat); if (!match.Success) { result = new string[1]; result[0] = input; return(result); } else { List <string> al = new List <string>(); if (!regex.RightToLeft) { int prevat = 0; for (; ;) { al.Add(input.Substring(prevat, match.Index - prevat)); 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)) { al.Add(match.Groups[i].ToString()); } } if (--count == 0) { break; } match = match.NextMatch(); if (!match.Success) { break; } } al.Add(input.Substring(prevat, input.Length - prevat)); } else { int prevat = input.Length; for (; ;) { al.Add(input.Substring(match.Index + match.Length, prevat - match.Index - match.Length)); prevat = match.Index; // add all matched capture groups to the list. for (int i = 1; i < match.Groups.Count; i++) { if (match.IsMatched(i)) { al.Add(match.Groups[i].ToString()); } } if (--count == 0) { break; } match = match.NextMatch(); if (!match.Success) { break; } } al.Add(input.Substring(0, prevat)); al.Reverse(0, al.Count); } return(al.ToArray()); } }
/// <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> internal static string Replace(MatchEvaluator evaluator, Regex regex, string input, int count, int startat) { if (evaluator == null) { throw new ArgumentNullException(nameof(evaluator)); } if (count < -1) { throw new ArgumentOutOfRangeException(nameof(count), SR.CountTooSmall); } if (startat < 0 || startat > input.Length) { throw new ArgumentOutOfRangeException(nameof(startat), SR.BeginIndexNotNegative); } if (count == 0) { return(input); } Match match = regex.Match(input, startat); if (!match.Success) { return(input); } else { StringBuilder sb = new StringBuilder(); if (!regex.RightToLeft) { int prevat = 0; do { if (match.Index != prevat) { sb.Append(input, prevat, match.Index - prevat); } prevat = match.Index + match.Length; sb.Append(evaluator(match)); if (--count == 0) { break; } match = match.NextMatch(); } while (match.Success); if (prevat < input.Length) { sb.Append(input, prevat, input.Length - prevat); } } else { List <string> al = new List <string>(); int prevat = input.Length; do { if (match.Index + match.Length != prevat) { al.Add(input.Substring(match.Index + match.Length, prevat - match.Index - match.Length)); } prevat = match.Index; al.Add(evaluator(match)); if (--count == 0) { break; } match = match.NextMatch(); } while (match.Success); if (prevat > 0) { sb.Append(input, 0, prevat); } for (int i = al.Count - 1; i >= 0; i--) { sb.Append(al[i]); } } return(sb.ToString()); } }