You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TMemo组件中选中指定文本的第二次出现位置

TMemo 不区分大小写查找并选中第二次出现的指定文本

实现思路

首次匹配完成后,从首次匹配结束的下一个字符位置开始,搜索剩余的文本内容,即可得到第二次匹配的位置。

方案1:使用原生Pos函数实现(无需额外引用单元)

通过截断文本的方式跳过第一次匹配的区间,对剩余文本执行搜索:

var
  SearchStr: string;
  LowerMemoText: string;
  FirstMatchPos: Integer;
  SecondMatchPos: Integer;
  SearchStrLen: Integer;
begin
  SearchStr := 'Text';
  SearchStrLen := Length(SearchStr);
  // 统一转小写实现不区分大小写匹配
  LowerMemoText := AnsiLowerCase(Memo1.Text);

  // 查找第一次匹配的位置(字符串索引1基)
  FirstMatchPos := Pos(AnsiLowerCase(SearchStr), LowerMemoText);
  if FirstMatchPos = 0 then Exit; // 无匹配直接返回

  // 截取第一次匹配结束后的剩余文本,查找第二次匹配
  SecondMatchPos := Pos(AnsiLowerCase(SearchStr), Copy(LowerMemoText, FirstMatchPos + SearchStrLen, MaxInt));
  if SecondMatchPos = 0 then Exit; // 无第二次匹配直接返回

  // 转换为TMemo的0基SelStart坐标
  Memo1.SelStart := (FirstMatchPos + SearchStrLen - 1) + (SecondMatchPos - 1);
  Memo1.SelLength := SearchStrLen;
  Memo1.SetFocus;
end;

方案2:使用PosEx函数实现(代码更简洁)

PosEx支持指定搜索起始位置,需先引用StrUtils单元:

// 接口部分引用StrUtils单元
uses
  ..., StrUtils;

procedure TForm1.Button1Click(Sender: TObject);
var
  SearchStr: string;
  LowerMemoText: string;
  FirstMatchPos: Integer;
  SecondMatchPos: Integer;
  SearchStrLen: Integer;
begin
  SearchStr := 'Text';
  SearchStrLen := Length(SearchStr);
  LowerMemoText := AnsiLowerCase(Memo1.Text);

  FirstMatchPos := PosEx(AnsiLowerCase(SearchStr), LowerMemoText, 1);
  if FirstMatchPos = 0 then Exit;

  // 直接指定从第一次匹配结束的下一位开始搜索
  SecondMatchPos := PosEx(AnsiLowerCase(SearchStr), LowerMemoText, FirstMatchPos + SearchStrLen);
  if SecondMatchPos = 0 then Exit;

  Memo1.SelStart := SecondMatchPos - 1;
  Memo1.SelLength := SearchStrLen;
  Memo1.SetFocus;
end;

扩展说明

如果需要查找第N次出现的位置,只需循环调用PosEx,每次传入上一次匹配结束的位置作为下一轮的搜索起始位置即可。


内容的提问来源于stack exchange,提问作者Codrut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:15:03