Конференция "Прочее" » А нет ли случаем такого готового класса?
 
  • DVM © (18.12.08 22:41) [0]
    Аналог StringReplace(), но только для массовых замен.
    Т.е. на вход подаем исходную строку, в которой надо заменять и список пар
    "что меняем" - "на что заменять". Таких пар может быть много (сотни, тысячи).
    Понятно, что это можно реализовать многократным вызовом StringReplace, но что-то мне кажется, что есть более оптимальный путь. Не встречал ли кто подобного?
  • Anatoly Podgoretsky © (18.12.08 22:43) [1]
    > DVM  (18.12.2008 22:41:00)  [0]

    Если символ на символ, то эффективен цикл по строке.
  • DVM © (18.12.08 22:44) [2]

    > Если символ на символ,

    не строка на строку
  • DVM © (18.12.08 22:54) [3]
    Суть в следующем:
    Есть html шаблон страницы, в который в определенные места сервер должен при генерации страницы вставлять определенные значения. Места в шаблоне отмечены, скажем, так:
    {myvar1} или так {myvar2}. Таких мест много и они разные.

    Делать через StringReplace() на мой взгляд нерационально, т.к. получается следующее:

    s := 'исходная страница';
    s := StringReplace(заменяем первое значение);
    ...
    s := StringReplace(заменяем n-ое значение);

    Туда-сюда гоняем строки, на мой взгляд это неоптимально.
  • Игорь Шевченко © (18.12.08 23:07) [4]
    Я писал нечто подобное на основе примитивного разделения исходного текста на лексемы, пары исходное-значение/новое-значение организовывал в хэш-таблицу, ну а дальше все просто - вычисляется хэш лексемы, далее по таблице и на замену.

    Выкладывать не буду - оно у меня было написано на С.
  • Leonid Troyanovsky © (18.12.08 23:09) [5]

    > DVM ©   (18.12.08 22:54) [3]

    See CopyPrsr.TCopyParser

    --
    Regards, LVT.
  • Leonid Troyanovsky © (18.12.08 23:17) [6]

    > Leonid Troyanovsky ©   (18.12.08 23:09) [5]

    or see TPageProducer

    --
    Regards, LVT.
  • palva © (18.12.08 23:24) [7]

    > это можно реализовать многократным вызовом StringReplace,
    >  но что-то мне кажется, что есть более оптимальный путь.
    >  Не встречал ли кто подобного?

    Встречали, конечно. В php есть функция str_replace, аргументы которой могут быть массивами.

    Для эффективной замены в строке без создания новой строки напишите свою функцию или найдите где-нибудь готовую. Я написал себе вот такую:

    procedure Splice(var Str: String; Pos, LenI: Integer; Ins: String);
    {
     Замена фрагмента строки Str другой строкой Ins
     Pos - позиция начала заменяемого фрагмента
     LenI - длина заменяемого фрагмента
    }

    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.
  • antonn © (18.12.08 23:34) [8]

    > DVM ©   (18.12.08 22:54) [3]

    собсно для той же цели и делал, тупо - проход в цикле по парам и к каждой вызов замены :) правда странички весят не по мегабайту, падения скорости не заметно...
  • DVM © (18.12.08 23:44) [9]

    > 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

    Я думал про него уже. Хоть как раз для этого предназначен, но в моем случае из пушки по воробьям будет и опять же не быстро.
  • DVM © (18.12.08 23:47) [10]

    > antonn ©   (18.12.08 23:34) [8]


    > собсно для той же цели и делал, тупо - проход в цикле по
    > парам и к каждой вызов замены :) правда странички весят
    > не по мегабайту, падения скорости не заметно...

    Да в моем случает тоже пока не заметно. Но это пока количество замен небольшое. Да и некузяво это строки туда сюда плюсовать.
  • SPeller © (19.12.08 01:40) [11]

    > Не встречал ли кто подобного?

    из 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;



    заменит всё
  • KilkennyCat © (19.12.08 04:03) [12]

    > многократным вызовом StringReplace

    Просто надо не по тексту бегать, а по списку заменяемых значений. Как правило, изменяемый текст больше размером.
    Однократно идем по тексту кусками, кратными наименьшему заменяемому значению, накапливая буфер, равный наибольшему заменяемому значению, и сравниваем. В таком варианте скорость будет в разы больше многократного вызова реплэйса.
  • Сергей М. © (19.12.08 08:39) [13]

    > DVM


    TRegExpr.Replace[Ex]
 
Конференция "Прочее" » А нет ли случаем такого готового класса?
Есть новые Нет новых   [134449   +17][b:0][p:0.001]