我如何 select TMemo 中文本的第二个副本

How can I select the second copy of a text in a TMemo

我有一个 TMemo 里面有文字,例如:

Text1
Hello World!
Sky
Text123

我使用一个简单的函数 select 第一次找到文本

Memo1.SelStart := Pos(AnsiLowerCase('Text'), AnsiLowerCase(Memo1.Text)) - 1;
    Memo1.SelLength := Length('Text');
    Memo1.SetFocus;

我使用了 AnsiLowerCase 这样我就可以在不需要正确大写的情况下找到文本。

那么,如何select第二次在备忘录中出现“文本”?

您可以使用 Pos 函数的 Offset 参数以避免从头开始搜索并跳过第一个匹配项。

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.

例如:

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;