Reputation: 332
I have a TMemo
with text inside it, for example:
Text1
Hello World!
Sky
Text123
I use a simple function to select the first time a text was found
Memo1.SelStart := Pos(AnsiLowerCase('Text'), AnsiLowerCase(Memo1.Text)) - 1;
Memo1.SelLength := Length('Text');
Memo1.SetFocus;
I used AnsiLowerCase
so I can find text without the need for proper capitalization.
So, how can I select the second time "text" appears in the Memo?
Upvotes: 1
Views: 2374
Reputation: 8043
You can use the Offset
parameter of the Pos function in order to avoid starting search from the beginning and skip the first occurrence.
Locates a substring in a given string.
The Pos method returns the index of the first occurence of Substr in Str, starting the search at Offset.
This method returns zero if Substr is not found or Offset is invalid (for example, if Offset exceeds the String length or is less than 1).
The Offset argument is optional. Offset is set to 1 by default, if no value for Offset is specified it takes the default value to start the search from the beginning.
Notes:
Pos uses one-based array indexing even in platforms where the strings are zero-based.
Pos method is equivalent to System.StrUtils.PosEx.
For example:
procedure SearchNext(AMemo : TMemo; const ATextToSearch : string; ACycle : Boolean = True);
var
Offset : Integer;
begin
//adjusting offset
Offset := AMemo.SelStart + AMemo.SelLength + 1;
if(Offset >= Length(AMemo.Text)) then
Offset := 1;
//searching
Offset := Pos(AnsiLowerCase(ATextToSearch), AnsiLowerCase(AMemo.Text), Offset);
if(Offset > 0) then
begin
//selecting found text
AMemo.SelStart := Offset - 1;
AMemo.SelLength := Length(ATextToSearch);
AMemo.SetFocus;
end else
begin
//recursion from the beginning
if(ACycle and (AMemo.SelStart + AMemo.SelLength <> 0)) then
begin
AMemo.SelStart := 0;
SearchNext(AMemo, ATextToSearch, True);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SearchNext(Memo1, Edit1.Text);
end;
Upvotes: 1