如何在 RichEdit 中仅突出显示包含 'MyString' 的行?
How to highlight only the lines contain the 'MyString' in a RichEdit?
我创建了一个读取文本文件的小程序。
在 RichEdit 中打开文本文件后,我想更改包含特定字符串的行的背景颜色,或隐藏所有不包含该字符串的行。
可能吗?
我已经尝试搜索字符串,但我不知道如何执行我要求的操作。
function SearchText(Control: TCustomEdit; Search: string; SearchOptions: TSearchOptions): Boolean;
var
Text: string;
Index: Integer;
begin
if soIgnoreCase in SearchOptions then
begin
Search := UpperCase(Search);
Text := UpperCase(Control.Text);
end
else
Text := Control.Text;
Index := 0;
if not (soFromStart in SearchOptions) then
Index := PosEx(Search, Text, Control.SelStart + Control.SelLength + 1);
if (Index = 0) and
((soFromStart in SearchOptions) or
(soWrap in SearchOptions)) then
Index := PosEx(Search, Text, 1);
Result := Index > 0;
if Result then
begin
Control.SelStart := Index - 1;
Control.SelLength := Length(Search);
end;
end;
这是一个糟糕的 SO 问题,因为它有点像“请为我编写代码”。
自然的方法是找到问题的独立部分:
如何在Delphi中表示字符串数组(行)?
如何将 Delphi 中的文本文件加载到一些 in-memory 字符串数组中?
如何在Delphi的字符串中搜索子串?
如何过滤 Delphi in-memory 字符串数组? [如果您知道 1 并且听说过循环,那么这很简单。高效地做起来更有趣。]
如何填充 Delphi TRichEdit
控件?
的确,如果您知道 1--5 的答案,那么做您想做的事就很简单了!
我现在可能看起来像一个脾气暴躁的老人,但我认为我确实有一个关于如何处理编程问题的非常重要的观点。
无论如何,让我们一次解决一个问题:
array of string
的 old-school 方法,今天写成 TArray<string>
有效。这是一个动态的字符串数组。由于 Delphi 动态数组由编译器管理,它们很方便,因为您不需要手动创建和释放它们。但是,它们有点 low-level 并且有时会被误用。
可能更好的选择是使用 TStringList
class.
在 IOUtils
中,您会发现 TFile.ReadAllLines
将文件名和 returns(文本)文件的内容作为字符串数组。
如果您有 TStringList
,请使用 TStringList.LoadFromFile
。
传统上,您会使用 Pos
函数。但是今天你可以使用 string
助手:MyString.Contains()
。显然,您需要决定是否要将大写字母和小写字母视为相同。
根据 3.
中的测试,使用简单的 for
或 for in
循环从原始数组填充第二个数组
如果你有 TStringList
,只需使用 TRichEdit.Lines.Assign
。
将它们放在一起,使用 string
数组和 TStringList
:
的相当巧妙的组合
procedure TForm1.Button1Click(Sender: TObject);
begin
var Lines := TFile.ReadAllLines('K:\test.txt');
var FilteredLines := TStringList.Create;
try
for var Line in Lines do
if Line.Contains('MyString') then
FilteredLines.Add(Line);
RichEdit1.Lines.Assign(FilteredLines);
finally
FilteredLines.Free;
end;
end;
搜索和过滤文本然后将其放入 RichEdit 是最好的。
但是,如果文本已经加载到 RichEdit 中,TRichEdit
确实有一个可以使用的 FindText()
方法,您不应该搜索它的 Text
属性 手动。例如:
function SearchText(Control: TCustomRichEdit; const Search: string; SearchOptions: TSearchOptions): Boolean;
var
StartPos, SearchLen, Index: Integer;
Options: TSearchTypes;
begin
if soIgnoreCase in SearchOptions then
Options := []
else
Options := [stMatchCase];
if soFromStart in SearchOptions then
begin
StartPos := 0;
SearchLen := Control.GetTextLen;
Index := Control.FindText(Search, StartPos, SearchLen, Options);
end else
begin
StartPos := Control.SelStart + Control.SelLength;
SearchLen := Control.GetTextLen - StartPos;
Index := Control.FindText(Search, StartPos, SearchLen, Options);
if (Index = -1) and (soWrap in SearchOptions) then
Index := Control.FindText(Search, 0, StartPos, Options);
end;
Result := Index <> -1;
if Result then
begin
Control.SelStart := Index;
Control.SelLength := Length(Search);
end;
end;
也就是说,设置线条的背景颜色或删除线条(没有“隐藏”线条的选项)非常简单。
给定任何字符索引,您可以向 RichEdit 发送 EM_LINEFROMCHAR
消息以确定该字符出现的行索引。
然后您可以使用 TRichEdit.Lines.Delete()
方法从 RichEdit 中删除该行。
设置线条的背景颜色需要几个步骤:
发送 RichEdit EM_LINEINDEX
and EM_LINELENGTH
消息以确定行的开始和结束字符索引。
设置 RichEdit 的 SelStart
和 SelLength
属性(或向 RichEdit 发送 EM_EXSETSEL
消息)。
向 RichEdit 发送一条 EM_SETCHARFORMAT
message, specifying the SCF_SELECTION flag and using the CHARFORMAT2
记录,以设置所选内容的背景颜色。
我创建了一个读取文本文件的小程序。
在 RichEdit 中打开文本文件后,我想更改包含特定字符串的行的背景颜色,或隐藏所有不包含该字符串的行。 可能吗?
我已经尝试搜索字符串,但我不知道如何执行我要求的操作。
function SearchText(Control: TCustomEdit; Search: string; SearchOptions: TSearchOptions): Boolean;
var
Text: string;
Index: Integer;
begin
if soIgnoreCase in SearchOptions then
begin
Search := UpperCase(Search);
Text := UpperCase(Control.Text);
end
else
Text := Control.Text;
Index := 0;
if not (soFromStart in SearchOptions) then
Index := PosEx(Search, Text, Control.SelStart + Control.SelLength + 1);
if (Index = 0) and
((soFromStart in SearchOptions) or
(soWrap in SearchOptions)) then
Index := PosEx(Search, Text, 1);
Result := Index > 0;
if Result then
begin
Control.SelStart := Index - 1;
Control.SelLength := Length(Search);
end;
end;
这是一个糟糕的 SO 问题,因为它有点像“请为我编写代码”。
自然的方法是找到问题的独立部分:
如何在Delphi中表示字符串数组(行)?
如何将 Delphi 中的文本文件加载到一些 in-memory 字符串数组中?
如何在Delphi的字符串中搜索子串?
如何过滤 Delphi in-memory 字符串数组? [如果您知道 1 并且听说过循环,那么这很简单。高效地做起来更有趣。]
如何填充 Delphi
TRichEdit
控件?
的确,如果您知道 1--5 的答案,那么做您想做的事就很简单了!
我现在可能看起来像一个脾气暴躁的老人,但我认为我确实有一个关于如何处理编程问题的非常重要的观点。
无论如何,让我们一次解决一个问题:
array of string
的 old-school 方法,今天写成TArray<string>
有效。这是一个动态的字符串数组。由于 Delphi 动态数组由编译器管理,它们很方便,因为您不需要手动创建和释放它们。但是,它们有点 low-level 并且有时会被误用。可能更好的选择是使用
TStringList
class.在
IOUtils
中,您会发现TFile.ReadAllLines
将文件名和 returns(文本)文件的内容作为字符串数组。如果您有
TStringList
,请使用TStringList.LoadFromFile
。传统上,您会使用
Pos
函数。但是今天你可以使用string
助手:MyString.Contains()
。显然,您需要决定是否要将大写字母和小写字母视为相同。根据 3.
中的测试,使用简单的for
或for in
循环从原始数组填充第二个数组如果你有
TStringList
,只需使用TRichEdit.Lines.Assign
。
将它们放在一起,使用 string
数组和 TStringList
:
procedure TForm1.Button1Click(Sender: TObject);
begin
var Lines := TFile.ReadAllLines('K:\test.txt');
var FilteredLines := TStringList.Create;
try
for var Line in Lines do
if Line.Contains('MyString') then
FilteredLines.Add(Line);
RichEdit1.Lines.Assign(FilteredLines);
finally
FilteredLines.Free;
end;
end;
搜索和过滤文本然后将其放入 RichEdit 是最好的。
但是,如果文本已经加载到 RichEdit 中,TRichEdit
确实有一个可以使用的 FindText()
方法,您不应该搜索它的 Text
属性 手动。例如:
function SearchText(Control: TCustomRichEdit; const Search: string; SearchOptions: TSearchOptions): Boolean;
var
StartPos, SearchLen, Index: Integer;
Options: TSearchTypes;
begin
if soIgnoreCase in SearchOptions then
Options := []
else
Options := [stMatchCase];
if soFromStart in SearchOptions then
begin
StartPos := 0;
SearchLen := Control.GetTextLen;
Index := Control.FindText(Search, StartPos, SearchLen, Options);
end else
begin
StartPos := Control.SelStart + Control.SelLength;
SearchLen := Control.GetTextLen - StartPos;
Index := Control.FindText(Search, StartPos, SearchLen, Options);
if (Index = -1) and (soWrap in SearchOptions) then
Index := Control.FindText(Search, 0, StartPos, Options);
end;
Result := Index <> -1;
if Result then
begin
Control.SelStart := Index;
Control.SelLength := Length(Search);
end;
end;
也就是说,设置线条的背景颜色或删除线条(没有“隐藏”线条的选项)非常简单。
给定任何字符索引,您可以向 RichEdit 发送 EM_LINEFROMCHAR
消息以确定该字符出现的行索引。
然后您可以使用 TRichEdit.Lines.Delete()
方法从 RichEdit 中删除该行。
设置线条的背景颜色需要几个步骤:
发送 RichEdit
EM_LINEINDEX
andEM_LINELENGTH
消息以确定行的开始和结束字符索引。设置 RichEdit 的
SelStart
和SelLength
属性(或向 RichEdit 发送EM_EXSETSEL
消息)。向 RichEdit 发送一条
EM_SETCHARFORMAT
message, specifying the SCF_SELECTION flag and using theCHARFORMAT2
记录,以设置所选内容的背景颜色。