Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.04.2010, 09:02   #1
kaizer131
Пользователь
 
Регистрация: 21.03.2009
Сообщений: 52
По умолчанию Работа с 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() и подобные функции нельзя
Движение - жизнь. Остановка - ... ?

Последний раз редактировалось kaizer131; 09.04.2010 в 10:19. Причина: уточнение
kaizer131 вне форума Ответить с цитированием
Старый 09.04.2010, 10:03   #2
SERG1980
Участник клуба
 
Аватар для SERG1980
 
Регистрация: 28.03.2007
Сообщений: 1,814
По умолчанию

Могу вам подкинуть поиск и выделение найденого слова в ричэдит
Код:
 
uses RichEdit;

implementation

{$R *.dfm}
 const EM_SCROLLCARET = $00B7;
 var R:FINDTEXT;
 Rres:CHARRANGE;
 s:string;
 Flags:longint;
procedure TForm1.Button1Click(Sender: TObject);
begin
 R.chrg.cpMin:=0;
 R.chrg.cpMax:=Length(RichEdit1.Text);
 s:=Edit1.Text;//искомое слово
 R.lpstrText:=PChar(s);
 Flags:=0;
 repeat
  Rres.cpMin:=RichEdit1.Perform(EM_FINDTEXT,Flags,Longint(@R));
  Rres.cpMax:=RRes.cpMin+Length(Edit1.Text);
  Application.ProcessMessages;
  RichEdit1.Perform(EM_EXSETSEL,0,LongInt(@Rres));
  RichEdit1.SelAttributes.Color:= clRed;
  R.chrg.cpMin:=Rres.cpMax;
  RichEdit1.Perform(EM_SCROLLCARET,0,0);
  RichEdit1.SetFocus;
 until Rres.cpMin=-1;
end;
если нужно учитывать регистр при поиске то переменной Flags выставите значение Flags:=FT_MATCHCASE;
если слово целиком то Flags:=FT_WHOLEWORD;

Последний раз редактировалось SERG1980; 09.04.2010 в 10:20.
SERG1980 вне форума Ответить с цитированием
Старый 09.04.2010, 12:08   #3
kaizer131
Пользователь
 
Регистрация: 21.03.2009
Сообщений: 52
По умолчанию

попробовал так
не получилось
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,RichEdit, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    RichEdit1: TRichEdit;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


 const EM_SCROLLCARET = $00B7;
 var R:FINDTEXT;
 Rres:CHARRANGE;
 s:string;
 Flags:longint;
procedure TForm1.Button1Click(Sender: TObject);
begin
 R.chrg.cpMin:=0;
 R.chrg.cpMax:=Length(RichEdit1.Text);
 s:=Edit1.Text;//искомое слово
 R.lpstrText:=PChar(s);
 Flags:=0;
 repeat
  Rres.cpMin:=RichEdit1.Perform(EM_FINDTEXT,Flags,Longint(@R));
  Rres.cpMax:=RRes.cpMin+Length(Edit1.Text);
  Application.ProcessMessages;
  RichEdit1.Perform(EM_EXSETSEL,0,LongInt(@Rres));
  RichEdit1.SelAttributes.Color:= clRed;
  R.chrg.cpMin:=Rres.cpMax;
  RichEdit1.Perform(EM_SCROLLCARET,0,0);
  RichEdit1.SetFocus;
 until Rres.cpMin=-1;
end;
end.
Движение - жизнь. Остановка - ... ?
kaizer131 вне форума Ответить с цитированием
Старый 09.04.2010, 12:30   #4
SERG1980
Участник клуба
 
Аватар для SERG1980
 
Регистрация: 28.03.2007
Сообщений: 1,814
По умолчанию

А что именно, у меня например все найденные слова красным веделяет
Вложения
Тип файла: zip Поиск в RichEdit.zip (231.6 Кб, 49 просмотров)

Последний раз редактировалось SERG1980; 09.04.2010 в 12:32.
SERG1980 вне форума Ответить с цитированием
Старый 09.04.2010, 13:18   #5
kaizer131
Пользователь
 
Регистрация: 21.03.2009
Сообщений: 52
По умолчанию

Хм странно , твой ЕХЕ шник запустил, нормально всё работает, открыл проект , запустил, невыделяет, у тебя какая delphi?
У меня 2009... может в ней косяк ?
Движение - жизнь. Остановка - ... ?
kaizer131 вне форума Ответить с цитированием
Старый 09.04.2010, 13:33   #6
SERG1980
Участник клуба
 
Аватар для SERG1980
 
Регистрация: 28.03.2007
Сообщений: 1,814
По умолчанию

Может быть у меня 2006
SERG1980 вне форума Ответить с цитированием
Старый 09.04.2010, 14:24   #7
kaizer131
Пользователь
 
Регистрация: 21.03.2009
Сообщений: 52
По умолчанию

хм, может кто сталкивался с подобным?
Движение - жизнь. Остановка - ... ?
kaizer131 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с RichEdit xmaksimca Компоненты Delphi 1 24.12.2009 20:25
Работа с RichEdit в Delphi7 Ариил Помощь студентам 1 23.12.2009 15:21
Работа с RichEdit WinApi Igoressicus Помощь студентам 2 29.05.2009 21:31
Работа с Richedit vitamin.rulez Помощь студентам 2 28.01.2009 18:12
RichEdit - работа с Clipboard GAGARIN-NEW Компоненты Delphi 5 16.12.2007 20:30