Здравствуйте, в этой статье, я хотел бы поговорить о том, как можно реализовать поиск слов, строк и так далее, в компонентах TRichEdit и TMemo. С данными компонентами Вы уже работали, так что нам не составит труда организовать поиск, который я задумал. Итак, что за поиск, поясню поподробнее: сперва, мы просто определим, есть ли искомая строка, слово в данных компонентах, ну а в самом конце мы организуем поиск, который присутствует почти во всех текстовых редакторах, а также браузерах — «Найти далее«. То есть, другими словами, мы будем выделять слово, а потом, по нажатию повторно на кнопку, будем выделять другое слово (искомое), если такое еще имеется. Что касается TRichEdit, то здесь мы будем выделять эти все слова в нужный нам цвет, так как компонент нам это все позволяет. Мы за 1 раз в цикле пройдем по всему тексту, чтобы найти искомые слова, строки, а затем установим для них атрибуты, такие как: цвет, начертание и так далее, это уже по желанию.
Итак, что нам понадобится на первое время, компоненты следующие:
- TMemo
- TRichEdit
- TButton — 2 шт.
Сразу мы приступим к поиску слов (строк) в компоненте TMemo. Как я и говорил, мы найдем слово формально, то есть не выделяя его, а просто убедимся есть ли оно там вообще. Для этого нам понадобится функция pos. Итак, напишем следующий код:
procedure TForm1.Button3Click(Sender: TObject);
begin
if pos('слово',MemoText.Text)<>0 then
ShowMessage('Find text')
else
ShowMessage('not Find text');
end;
Здесь мы просто убеждаемся в наличии конкретного слова (строки) и так далее.
Теперь приступим к поиску слов (строк) с выделением их. Для этого нам придется установить фокус в наш компонент, а также в свойстве HideSelection установим в False (можно программно). На событие OnCreate TForm я инициализировал первоначальные переменные, которые нам понадобятся:
procedure TForm1.FormCreate(Sender: TObject);
begin
j:=0;
s_pos:='поиск';
i:=0;
end;
- s_pos - типа string, в которой находится слово (строка), которую будем искать в TMemo
- i,j - типа integer, необходимы для запоминания первоначальной позиции поиска слов (строк)
Итак, теперь код, который будет выделять слово (строку) первую, найденную в тексте
procedure TForm1.Button1Click(Sender: TObject);
begin
MemoText.SetFocus;
MemoText.HideSelection:=False;
MemoText.SelStart:=pos(s_pos,MemoText.Text)-1;
MemoText.SelLength:=Length(s_pos);
end;
Как видите, если повторно нажать на кнопку, то выделяться будет тоже самое слово (первое, найденное, не забываем, что мы ищем переменную s_pos, а в ней мы записали «поиск«, то есть мы ищем слово «поиск«), а не то, которое также еще имеется дальше по тексту. Для того, чтобы поиск работал последовательно и выделялись слова последовательно, как я уже и говорил раньше, необходимо запоминать позицию каждого, найденного слова (строки), а уже потом после этого найденного слова и начинать дальнейший поиск. На OnCreate TForm мы уже запомнили первоначальную позицию, она равняется 0, то есть сперва мы будем начинать поиск с первого символа, то есть с нулевой позиции. Для того, чтобы все искомые слова выделялись последовательно я написал следующий код:
procedure TForm1.Button1Click(Sender: TObject);
begin
MemoText.SetFocus;
MemoText.HideSelection:=False;
if pos(s_pos,MemoText.Text)<>0 then
begin
if j=0 then
begin
if (i<(posEx(s_pos,MemoText.Text,i)+1)) then
begin
MemoText.SelStart:=pos(s_pos,MemoText.Text)-1;
i:=i+length(s_pos);
MemoText.SelLength:=Length(s_pos);
end;
end
else
begin
if (i<(poseX(s_pos,MemoText.text,i)+1)) then
begin
MemoText.SelStart:=PosEx(s_pos,MemoText.Text,i)-1;
i:=i+length(s_pos);
MemoText.SelLength:=Length(s_pos);
end;
end;
end;
inc(j);
end;
Как видите, мы также здесь устанавливаем фокус, а также свойство HideSelection устанавливаем в False, ну а дальше с помощью функции posEx мы находим постепенно все искомые слова (строки) и выделяем их, как только находим последнее слово в тексте, то его выделяем и все дальше ничего не происходит, по желанию можно сделать, чтобы позиция устанавливалась на 0 и заново происходил поиск с самого начала текста. Ну, что немного с поиском текста в компоненте TMemo мы разобрались, теперь сделаем тоже самое только в компоненте TRichEdit, тут ничего нового не будет, одно лишь отличие, что в компоненте TRichEdit можно задавать начертание, цвет и так далее, что более красивее будет выглядеть. Для этого я написал следующий код:
procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
find_text:string;
begin
find_text:='слово';
i:=Pos(find_text,RichEditText.Text)-1;
while (i<=Length(RichEditText.Text)) do
begin
RichEditText.HideSelection:=False;
RichEditText.SelStart:=PosEx(find_text,RichEditText.Text,i)-1;
RichEditText.SelLength:=length(find_text);
RichEditText.SelAttributes.Color:=clRed;
Application.ProcessMessages;
i:=i+length(find_text);
end;
end;
Как видите, все почти тоже самое, только здесь организовываем цикл, чтобы выделить все искомые слова нужным цветом. Application.ProcessMessages применяем для того, чтобы в случае большого количества обработки текста не зависало наше приложение. Ну и с помощью SelAttributes мы можем задавать начертание тексту или цвет, что и делаем в нашем случае. Думаю теперь стало все понятно и можно в своих текстовых редакторах организовать хороший поиск, а также производить замену слов на синонимы и выделять их цветом (по такому принципу работают почти все синонимайзеры, только необходимо придумать очень быстрый алгоритм поиск и замены слов). Исходник, как всегда прилагается, скачать можно тут