Delphi XE, using Delphi's own RegularExpressions unit.
I'm attempting to correct some bad RTF code, where 'bookmark' tags cross the boundaries of a table cell. Seems simple enough. The code I'm using is below. Here's the general idea.
Given this text
{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^\cell}
Look for a match to this pattern (there should be exactly one in the given text):
{\\\*\\bkmkstart BM0}\\plain\\f[0-9]\\fs[0-9]+\\cf[0-9] \^\\cell}
When found, replace it with this (non-RegEx) string:
{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^{\*\bkmkend BM0}\plain\f0\fs24\cf0 \cell}
The expected results are that the first string should be replaced with the last string, eg:
{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^\cell} *becomes*
{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^{\*\bkmkend BM0}\plain\f0\fs24\cf0 \cell}
However, the result I'm actually getting is this:
{\*\bkmkstart BM0}\plain{\*\bkmkstart bm0}\plain\f0\fs24\cf0 ^\cell}\fs24\cf0 ^{\*\bkmkend BM0}\plain{\*\bkmkstart bm0}\plain\f0\fs24\cf0 ^\cell}\fs24\cf0 \cell}
It looks as if the RegEx parser is getting horribly confused somehow, but I can't even characterize what is happening. It's not a mere double replacement, or an insertion instead of replacement. The 'ReplaceWith' string does seem to be the source of the confusion, though. If I use a nice simple 'XXXX' for the ReplaceWith string, instead of the RTF, it works exactly as it should.
So, any ideas how/why the RegEx search/replace is breaking so strangely here?
Here is the code I'm using:
procedure TfrmMain.btnProcessClick(Sender: TObject);
const
SourceString = '{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^\cell}';
RegExFind = '{\\\*\\bkmkstart BM0}\\plain\\f[0-9]\\fs[0-9]+\\cf[0-9] \^\\cell}';
ReplaceWith = '{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^{\*\bkmkend BM0}\plain\f0\fs24\cf0 \cell}';
var
ResultStr: string;
MyRegEx: TRegEx;
begin
MyRegEx := TRegEx.Create (RegExFind);
ResultStr := MyRegEx.Replace (SourceString, ReplaceWith);
ShowMessage (ResultStr);
end;
TRegEx.Createwould make sense considering thatTRegExis a record.MyRegExtoFreeAndNil.....TRegEx.Createand assigning the result to a local variable of typeTRegEx. And then callingReplace()on that local variable. In other words your now deleted answer is simply expanded to the code in the question. Generally, when a library offers two alternative ways to do the same thing, it is unlikely that the answer to any question is to switch from one alternative to the other. For that to be the answer you'd need to know that the library in question had a broken implementation of one of the alternatives.