/// <summary> /// Replace all occurrences of patterns in a string /// /// The string is searched for all (non-overlapping) occurrences of patterns in this searcher, /// for each occurrence, the provided replacer is called to supply a replacement value for /// that part of the string. If it returns null, that part of the string remains unchanged. /// If it returns a String, then the pattern occurrence will be replaced with the string returned. /// </summary> /// <param name="src">the String to search</param> /// <param name="replacer">the <see cref="ReplacementSelector{TResult}"/> that provides new values for matches /// in the string</param> /// <returns>the new string with values replaced</returns> public string FindAndReplace(string src, ReplacementSelector <TResult> replacer) { var it = SearchString(src); StringReplaceAppendable dest = null; var doneTo = 0; while (it.MoveNext()) { var mr = it.Current; var s = it.MatchStartPosition; var e = it.MatchEndPosition; if (dest == null) { dest = new StringReplaceAppendable(src); } if (doneTo < s) { dest.Append(src, doneTo, s); } doneTo = replacer(dest, mr, src, s, e); if (doneTo <= 0) { doneTo = e; } else { if (doneTo <= s) { throw new DfaException("Replacer tried to rescan matched string"); } it.Reposition(doneTo); } } if (dest != null) { if (doneTo < src.Length) { dest.Append(src, doneTo, src.Length); } return(dest.ToString()); } return(src); }
/// <summary> /// Build a search and replace function from a searcher and replacer /// </summary> /// <param name="searcher">the searcher</param> /// <param name="replacer">the replacer</param> /// <typeparam name="TResult"></typeparam> /// <returns>The search+replace function</returns> public static Func <string, string> BuildFromSearcher <TResult>(StringSearcher <TResult> searcher, ReplacementSelector <TResult> replacer) { return(str => searcher.FindAndReplace(str, replacer)); }