在Delphi中搜索备忘录?

6

有没有简单的代码可以让我在备忘录中搜索一个简单的字符串,并在找到后将其高亮显示?

2个回答

11

这个搜索功能允许文档环绕、大小写敏感搜索和从光标位置开始搜索。

type
  TSearchOption = (soIgnoreCase, soFromStart, soWrap);
  TSearchOptions = set of TSearchOption;


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;

如果设置文本框的HideSelection属性为False,则即使该文本框失去焦点,也会显示选择文本。

使用方法如下:

  SearchText(Memo1, Edit1.Text, []);

还可以搜索编辑内容。


使用大写字母可能无法得到您想要的结果,例如在法语中,大写字符不能带有重音,而小写字符可以带有重音(这与加拿大法语不同,我认为,在那里大写字符也可以带重音)。因此,在这种情况下,使用小写字母会得到更好的结果。 - dummzeuch
重点是,带重音符号和不带重音符号的字母是两个不同的字母,对吧?一个法语单词,当转换为大写时会显示为PRIVé,在小写情况下会是privé。另一方面,大写字母É也不会被转换为é,所以我不明白这如何影响搜索结果。尽管我必须承认,我是在Delphi 7中测试这个功能的。如果Unicode或您的Delphi可能使用区域设置在使用LowerCase时产生更好的结果,请使用它们。 - GolezTrol
2
GolezTrol:感谢您的HideSelection提示! - RobertFrank

3
  function TForm1.FindText( const aPatternToFind: String):Boolean;
  var
    p: Integer;
  begin
    p := pos(aPatternToFind, Memo1.Text);
    Result :=  (p > 0);
    if Result then
      begin
        Memo1.SelStart := p;
        Memo1.SelLength := Length(aPatternToFind);
        Memo1.SetFocus; // necessary so highlight is visible
      end;
  end;

如果WordWrap为true,则此功能不会跨行搜索。


TStrings.Text 中搜索而不是 TStrings.Strings 是非常昂贵的,实际上是 2×N。 - Free Consulting
@user205376 - 你为什么这么说?TStrings.Text 是一个单一的字符串,我认为在上面使用 pos() 应该会很快。而像你所建议的,搜索 TStrings.Strings 将涉及到对每个字符串进行下标访问。在我看来,这样做会更慢,也不会提供任何比 pos() 更多的功能。而且,这还需要一些棘手的代码才能突出显示找到的模式。你为什么认为不是呢? - RobertFrank
有点晚了,但对于上面的问题,这取决于实现方式。毕竟TStrings是抽象的。Memo.Lines.Text (= TMemoStrings.Text)使用单个API调用获取备忘录的文本,而TStringList存储单独的字符串,TStringList.Text在每次请求时将它们组合成一个单一的字符串(顺便说一句,这通常仍然比调用API更快)。答案使用Memo1.Text,我认为它绕过了任何TStrings后代并直接在备忘录的句柄上调用了一些GetText api。 - GolezTrol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接