-
Аналог StringReplace(), но только для массовых замен. Т.е. на вход подаем исходную строку, в которой надо заменять и список пар "что меняем" - "на что заменять". Таких пар может быть много (сотни, тысячи). Понятно, что это можно реализовать многократным вызовом StringReplace, но что-то мне кажется, что есть более оптимальный путь. Не встречал ли кто подобного?
-
> DVM (18.12.2008 22:41:00) [0]
Если символ на символ, то эффективен цикл по строке.
-
> Если символ на символ,
не строка на строку
-
Суть в следующем: Есть html шаблон страницы, в который в определенные места сервер должен при генерации страницы вставлять определенные значения. Места в шаблоне отмечены, скажем, так: {myvar1} или так {myvar2}. Таких мест много и они разные.
Делать через StringReplace() на мой взгляд нерационально, т.к. получается следующее:
s := 'исходная страница'; s := StringReplace(заменяем первое значение); ... s := StringReplace(заменяем n-ое значение);
Туда-сюда гоняем строки, на мой взгляд это неоптимально.
-
Я писал нечто подобное на основе примитивного разделения исходного текста на лексемы, пары исходное-значение/новое-значение организовывал в хэш-таблицу, ну а дальше все просто - вычисляется хэш лексемы, далее по таблице и на замену.
Выкладывать не буду - оно у меня было написано на С.
-
> DVM © (18.12.08 22:54) [3]
See CopyPrsr.TCopyParser
-- Regards, LVT.
-
> Leonid Troyanovsky © (18.12.08 23:09) [5]
or see TPageProducer
-- Regards, LVT.
-
> это можно реализовать многократным вызовом StringReplace, > но что-то мне кажется, что есть более оптимальный путь. > Не встречал ли кто подобного?
Встречали, конечно. В php есть функция str_replace, аргументы которой могут быть массивами. Для эффективной замены в строке без создания новой строки напишите свою функцию или найдите где-нибудь готовую. Я написал себе вот такую:
procedure Splice(var Str: String; Pos, LenI: Integer; Ins: String);
var
Len, LenP, Diff, LenM: Integer;
begin
Len := Length(Str);
LenM := Len - Pos - LenI + 1;
if (LenI < 0) Or (Pos <= 0) Or (LenM < 0) then
raise Exception.Create('Wrong Splice parameter');
LenP := Length(Ins);
Diff := LenP - LenI;
if Diff > 0 then
SetLength(Str, Len + Diff);
if LenM > 0 then
Move(Str[Pos + LenI], Str[Pos + LenP], LenM);
if LenP > 0 then
Move(Ins[1], Str[Pos], LenP);
if Diff < 0 then
SetLength(Str, Len + Diff);
end;
Правда, теперь я ее не использую, поскольку перестал писать на делфи. Пользуюсь dot.net и классом StringBuilder.
-
> DVM © (18.12.08 22:54) [3]
собсно для той же цели и делал, тупо - проход в цикле по парам и к каждой вызов замены :) правда странички весят не по мегабайту, падения скорости не заметно...
-
> palva © (18.12.08 23:24) [7]
> В php есть функция str_replace
На PHP я ей и пользовался.
> Пользуюсь dot.net и классом StringBuilder.
Аналогично.
Но мне в данный момент для Delphi. Вобщем, понятно, сделаю свою. Я просто подумал, а нет ли в RTL готового класса какого мне незнакомого.
> Leonid Troyanovsky © (18.12.08 23:17) [6]
> or see TPageProducer
Я думал про него уже. Хоть как раз для этого предназначен, но в моем случае из пушки по воробьям будет и опять же не быстро.
-
> antonn © (18.12.08 23:34) [8]
> собсно для той же цели и делал, тупо - проход в цикле по > парам и к каждой вызов замены :) правда странички весят > не по мегабайту, падения скорости не заметно...
Да в моем случает тоже пока не заметно. Но это пока количество замен небольшое. Да и некузяво это строки туда сюда плюсовать.
-
> Не встречал ли кто подобного?
из KOL: function StrReplace( var S: String; const From, ReplTo: String ): Boolean;
var I: Integer;
begin
I := pos( From, S );
if I > 0 then
begin
S := Copy( S, 1, I - 1 ) + ReplTo + CopyEnd( S, I + Length( From ) );
Result := TRUE;
end
else Result := FALSE;
end; а потом вызов while StrReplace() do; заменит всё
-
> многократным вызовом StringReplace
Просто надо не по тексту бегать, а по списку заменяемых значений. Как правило, изменяемый текст больше размером. Однократно идем по тексту кусками, кратными наименьшему заменяемому значению, накапливая буфер, равный наибольшему заменяемому значению, и сравниваем. В таком варианте скорость будет в разы больше многократного вызова реплэйса.
-
> DVM
TRegExpr.Replace[Ex]
|