如何在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
相关产品推荐
相关产品推荐

