Показать сообщение отдельно
  #1  
Старый 09.04.2010, 09:06
kaizer131 kaizer131 вне форума
Начинающий
 
Регистрация: 01.11.2008
Сообщения: 112
Репутация: 10
По умолчанию Работа с RichEdit

Привет всем!

Не могу до конца проработать один момент. Организовываю поиск подстроки в тексте.
Для вывода текста используется 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() и подобные функции нельзя
Ответить с цитированием