You may want to divide the task:
1) identify the sequence to work on
2) (maybe part of 1) provide the new sequence
3) change the string
Though if done a certain way, 3 merges with the others do.
If your string is rather long (10k or 100k) and has lots of changes, then doing delete/insert (or any way of length change) repeatedly for each change is going to be slow.
In such a case you want to alloc a new string, maybe oversize it, (if need resize it every 1000 changes) and write to the new string, and cut it at the end. (use uniquestring on the target string, if working with pchar / SetLength replaces uniquestring)
Yes you need to copy the bits between the changes, but doing an insert/delete copies the entire rest of the string every single time.
A 2 pass solution may also work, calculate the new length then alloc and make changes...
-----------------------------------
So if you need to search for the next item, your callback needs
cb = function (ACurrentPos: PChar; ARemainingLen: integer; out ANextFound: PChar; out ANextLen: integer): boolean; // result indicates if anything was found at all
// Additionally returning the new length needed may help to allocate space
Your replacement code needs a location to read, and one to write
cb = procedure(AReadPos: Pchar; AReadLen: integer; AWritePos: Phcar; AwriteMaxLen: integer; out AWrittenLen: integer);
"WritePos" could point to the new over-allocated string, or a temp buffer from where you copy it into the existing string.
You can combine the 2 methods....