Привет всем!
Не могу до конца проработать один момент. Организовываю поиск подстроки в тексте.
Для вывода текста используется RichEdit. Необходимо найти все вхождения подстроки и выделить их красным цветом.
Пробовал 2 способа:
1) При нажатии кнопки проходить по тексту целиком, организовав в цикле проверку.
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
p,s: string; i,lp,j: integer;
BMT: PBMTable; // таблица смещений, полученная по алгоритму Бойера-Мура
begin
p:= edit1.text; // в переменную р заносим значение искомой подстроки
lp:=Length(p); // получаем длину подстроки
s:=RichEdit1.text; // в переменной s хранится весь текст из RichEdit1
BMT:=WCMakeBMTable(p); // вызов функции строящей таблицу смещений
// patpos глобальная переменная хранящая в себе позицию вхождения подстроки
while patpos<>0 do // пока есть вхождения
begin
memo2.Lines.Add(inttostr(BMSearch(PatPos,lp,s,BMT))); // в memo2 добавляем позиции вхождения
// следующий блок должен выделять найденную подстроку красным цветом
RichEdit1.SelStart:= PatPos -1; // начало выделения
RichEdit1.SelLength:=lp; // конец выделения
RichEdit1.SelAttributes.Color:= clRed; // выделенное выделяем красным
PatPos := BMSearch(PatPos+1,lp,s,BMT); // обновляем позицию вхождения
end;
FreeMem(BMT); // освобождаем память.
end;
В этом способе пока не могу исправить следующие ошибки:
1- в memo2 первое вхождение выводится 2 раза, остальные нормально.
2- Позиция PatPos, начиная со второй строки высчитывается неправильно.
Как я понимаю это из за того что в конце каждой строки есть символы перехода на новую строку и возврата каретки #10#13.
Из этого следует вопрос, как их игнорировать ?
3- найденная подстрока выделяется только в первой строке.
2-ой способ – построчное считывание
Код:
procedure TForm1.Button1Click(Sender: TObject);
var p,s: string; i,lp,j,g: integer;
BMT: PBMTable;
begin
p:= edit1.text;
lp:=Length(p);
//ind:=0;
BMT:=WCMakeBMTable(p);
for j:=0 to RichEdit1.Lines.Count-1 do // проходим построчно RichEdit1
begin
s:= RichEdit1.Lines[j] ; //s назначается значение j – ой строки RichEdit
while patpos<>0 do
begin
memo2.Lines.Add(inttostr(BMSearch(PatPos,lp,s,BMT)));
RichEdit1.SelStart:= PatPos -1;
RichEdit1.SelLength:=lp;
RichEdit1.SelAttributes.Color:= clRed;
PatPos := BMSearch(PatPos+1,lp,s,BMT); // назначаем новый PatPos
end;
patpos:=1;
end;
end;
В этом способе пока не могу исправить следующие ошибки:
1- В memo2 первое вхождение выводится 2 раза, остальные нормально.
2- Как правильно просчитать PatPos, поскольку сейчас она считает её отдельно для каждой строки.
3- Найденная подстрока выделяется только в первой строке.
Так как мои мысли "замылились" прошу Вашего свежего взгляда и дельного совета
Забыл уточнить , все поиски осуществляются с помощью алгоритма Бойера-Мура, использовать pos() и подобные функции нельзя