![]() |
|
#1
|
|||
|
|||
![]() Привет всем!
Не могу до конца проработать один момент. Организовываю поиск подстроки в тексте. Для вывода текста используется 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() и подобные функции нельзя Последний раз редактировалось kaizer131, 09.04.2010 в 10:19. |
#2
|
|||
|
|||
![]() Я вот сейчас занимаюсь подобным проектом, только проверяю не весь текст а слово введенное в данный момент, ну т.е. от пробела до пробела. Была подобная проблема, выделялся не тот текст, выделялся участок на 2-3 позиции раньше. В моем случае помогло добавить к SelStart +(y*2), где y-номер строки в RichEdit, начиная с 0 естественно. Можете попробовать, но это в моем коде так, может у вас это работать не будет.
|