Подсветить символы в RichEdit
Иногда бывает так: есть какой-то текст, с виду обычный, ни чем не примечательный текст. А все буквы в нём заменены на аналоги в русском/английском. Выглядит так же, а для проверки на уникальность или для поисковых систем, скажем, не очень хороший текст.
Итак, поставим простую задачу: выделить цветом все русские (или английские буквы) в RichEdit.
Вспомним ASCII-коды букв: 192-255 для русских, 65-90 и 97-122 для английских.
Теперь нам нужно пройтись циклом по всем буквам, выделяя их и проверяя:
procedure TForm1.SpeedButton1Click(Sender: TObject); var i: Integer; Selected: Char; begin for i:=0 to Length(RichEdit1.Lines.Text)-1 do begin RichEdit1.SelStart:=i; RichEdit1.SelLength:=1; if Length(RichEdit1.SelText)<>1 then Continue; Selected:=RichEdit1.SelText[1]; case ord(Selected) of 192..255{рус}: RichEdit1.SelAttributes.Color:=clRed; else RichEdit1.SelAttributes.Color:=clBlack; end; // case end; end;
Проверку на длину выделенного символа сделал, так как вылетал access violation error, скорее всего в связи с переходами на новую строку, нашёл это решение на http://www.cyberforum.ru/.
Итак, вся суть в свойствах SelStart, SelLength и SelText. Таким образом можно выделить произвольный фрагмент и получить его содержание. А с помощью SelAttributes присвоить какой-нибудь стиль выделенному фрагменту. Я сделал шрифт красным.
Скачать исходник и готовую программу: подсветка символов в RichEdit
UPD. Читатели напоминают про методы BeginUpdate и EndUpdate, которые целесообразно разместить в начале и конце функции. Особенно разница будет заметна при больших объёмах текста.
Давно у меня не было подробных больших постов. Больше всего люблю их писать, да и интересно получается. Вот например: решение судоку на delphi. Там я полностью описал алгоритм решения, есть исходник и полностью рабочая программа. Люди уже курсовые по ней писали – минимум три человека в аську стучало, совета просили по коду :)
Крайне неэффективный алгоритм. Система будет тратить кучу времени на прорисовку всех этих селектов, хотя большинство из них и не нужны.
Вначале нужно узнать длину всего текста и записать в переменную, чтобы не проверять каждый раз.
Текст вначале скопировать в отдельную переменную, чтобы не вызывать методы конвертации текста в строку каждый раз для каждого символа.
Вместо селекта нужно напрямую проверять символ в строке — S[i] in SetRus, а то может вообще в тексте нет русских букв, а выделять приходится все.
Выделять не каждый символ отдельно, а вначале узнать длину русского слова, желательно вместе с пробелами и выделять уже его целиком.
Перед изменением контрола заблокировать его обновление через BeginUpdate.
Спасибо за замечания, со всем согласен.
Была цель написать в короткий срок для проверки небольших текстов
если согласен что тогда не изменил ?
Неплохо было бы вызвать методы
Rich.BeginUpdate
Rich.EndUpdate
чтобы не тратить кучу времени на лишнюю перерисовку, т.к. она занимает о-о-очень много времени(у меня ~10 к 1)
Сначало сделал, а потом прочитал комментарий. Вот она невнимательность :(
if Length(RichEdit1.SelText)1 then begin
Continue;
Selected:=RichEdit1.SelText[1];
case ord(Selected) of
192..255{рус}: RichEdit1.SelAttributes.Color:=clRed;
end
else
RichEdit1.SelAttributes.Color:=clBlack;
end; // case
end;
IF в begin — end не надо обрамить? а то при выполнении выполняется только Continue.
так и задумано, что только continue, даже по отступам видно
Можно провести аналогию с системой проверки орфографии. Только та работает в отдельном потоке, на лету, а это так сказать, один раз запустить) Кстати, кто сможет подсказать, как подчеркнуть слово в TRichEdit волнистой чертой?