2013-11-18 3 views
4

Delphi XE, используя собственный модуль регулярных выражений Delphi.Неожиданное поведение RegEx в Delphi XE

Я пытаюсь исправить какой-то плохой RTF-код, где теги «закладки» пересекают границы ячейки таблицы. Кажется достаточно простым. Код, который я использую, приведен ниже. Вот общая идея.

Учитывая этот текст

{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^\cell} 

Посмотрите на матч к этой модели (должно быть ровно один в данном тексте):

{\\\*\\bkmkstart BM0}\\plain\\f[0-9]\\fs[0-9]+\\cf[0-9] \^\\cell} 

Когда, замените его с этим (не RegEx):

{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^{\*\bkmkend BM0}\plain\f0\fs24\cf0 \cell} 

Ожидаемые результаты: первая строка должна быть заменена на la й строки, например:

{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^\cell} *becomes* 
{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^{\*\bkmkend BM0}\plain\f0\fs24\cf0 \cell} 

Однако, результат на самом деле я получаю это:

{\*\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} 

Это выглядит так, как если RegEx анализатор становится ужасно запутался как-то, но я не могу даже характеризуют то, что происходит. Это не просто двойная замена, а вставка вместо замены. Однако строка 'ReplaceWith' кажется источником путаницы. Если я использую хороший простой «XXXX» для строки ReplaceWith, вместо RTF, он работает точно так, как должен.

Итак, любые идеи о том, как/почему поиск и замена RegEx здесь так странно ломаются?

Вот код, я использую:

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; 
+0

Кроме того: я ненавижу Emba dev, который решил, что «TRegEx.Create» будет иметь смысл, учитывая, что «TRegEx» - это запись. –

+0

Я предположил, что .create был сделан здесь, чтобы проиллюстрировать расширенные возможности записи, так что, например, я, как я, мог бы дать ему завихрение. –

+0

Это становится захватывающим, когда вы pas 'MyRegEx'' FreeAndNil' ..... –

ответ

3

Вы должны избежать \ символов в строке замены:

ReplaceWith = '{\\*\\bkmkstart BM0}\\plain\\f0\\fs24\\cf0 ^{\\*\\bkmkend BM0}\\plain\\f0\\fs24\\cf0 \\cell}'; 

Когда вы сделаете это изменение выходным является:

 
{\*\bkmkstart BM0}\plain\f0\fs24\cf0 ^{\*\bkmkend BM0}\plain\f0\fs24\cf0 \cell} 

Фактически, для вашей заменяющей строки вам нужно только избежать обратной косой черты в \ f0, который, как это бывает, появляется дважды. Лично я считаю, что легче просто избежать обратной косой черты.

Объединив регулярные выражения и RTF, вы смешали свой специальный суп с обратной косой чертой - осторожно протрите. Просто будьте благодарны, что вы не используете C или более старые версии C++, которые не поддерживают исходные строки. Этот суп с обратной косой будет абсолютно неприятным!

+0

Ну, пугало. Это делает трюк, Дэвид, спасибо. Мне кажется странным, что заменяющая строка рассматривается как нечто иное, чем буквальное, но я возьму его. Похоже, что эта информация должна быть в документации, выделенной жирным шрифтом, курсивом и подчеркиванием. –

+0

Если вам не нужно было скрывать обратную косую черту, то как интерпретировать двигатель \ 1? Это буквальный \ 1, или это значение захвата? В любом случае документацию можно найти здесь: http://www.regular-expressions.info/, которая не там, где вы могли бы ожидать! –

+0

Моя ошибка заключалась в том, что я не ожидал, что двигатель должен будет интерпретировать заменяющую строку вообще. Мне показалось, что двигатель будет касаться только строки поиска. Найдя, я ожидал, что он просто заполнит заменяющую строку там, невзирая на содержимое заменяющей строки. Эта полезная утилита выполняет справедливую бит аналогичных манипуляций с документами RTF, и раньше мы не встречали ничего подобного. По-видимому, безумная удача. Еще раз спасибо! –

Смежные вопросы