I have created a small program the read a text file.
Once the text file is opened in a RichEdit, I want to change the background color of lines that contain a certain string, or to hide all lines that do not contain the string. Is it possible?
I have tried to search for the string, but I haven't any idea of how to do what I'm asking for.
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;
This is kind of a poor SO question, because it is a bit like "please write the code for me".
The natural approach would be to find the independent parts of the problem:
How to represent an array of strings (lines) in Delphi?
How to load a text file in Delphi into some in-memory array of strings?
How to search for a substring in a string in Delphi?
How to filter a Delphi in-memory array of strings? [This is trivial if you know 1 and has heard of loops. Doing it efficiently is slightly more interesting.]
How to populate a Delphi
TRichEditcontrol?Indeed, if you know the answers to 1--5, doing what you want is trivial!
I might seem like a very grumpy old man now, but I think I do have a very important point about how to approach a programming problem.
Anyhow, let us address one issue at a time:
The old-school approach of a
array of string, today writtenTArray<string>works. This is a dynamic array of strings. Since Delphi dynamic arrays are managed by the compiler, they are convenient because you don't need to create and free them manually. However, they are a bit low-level and are sometimes misused.Probably a better alternative for you is to use the
TStringListclass.In
IOUtils, you findTFile.ReadAllLineswhich takes a file name and returns the contents of the (text) file as an array of strings.Or use
TStringList.LoadFromFileif you have aTStringList.Traditionally, you would use the
Posfunction. But today you can use thestringhelper:MyString.Contains(). Obviously, you need to decide if you want to treat CAPITALS and small letters as identical or not.Use a trivial
fororfor inloop to populate a second array from the original array, based on the test from 3.If you have a
TStringList, just useTRichEdit.Lines.Assign.Putting it all together, using a fairly smart combination of
stringarrays andTStringList: