在2009年德尔福或更高版本(Unicode)的,有没有什么地方写任何内置函数或小程序,将做一个合理高效的整个词搜索中,您提供的定义的话,e.g分隔符:

function ContainsWord(Word, Str: string): boolean;

const  { Delim holds the delimiters that are on either side of the word }
  Delim = ' .;,:(){}"/\<>!?[]'#$91#$92#$93#$94'-+*='#$A0#$84;

其中:

Word: string;  { is the Unicode string to search for }
Str: string;   { is the Unicode string to be searched }

我只需要这个返回一个true或false值,如果“道”是字符串中

有必须有一些这个地方,因为标准查找对话框中有“仅匹配整个字”作为它的一个选项。

这是如何正常(或最佳)执行?


结论:

RRUZ的答案是完美的。该SearchBuf程序是我需要的。我甚至可以进入StrUtils常规,提取代码,并对其进行修改,以适应我的要求。

我很惊讶地发现,SearchBuf不会的单词第一个搜索,然后检查分隔符。相反,它在寻找一个分隔符时穿过一个字符串的字符。如果找到,则它会检查该字符串和另一个分隔符。如果没有找到它,它然后寻找另一个分隔符。出于效率的考虑,这是非常聪明!

有帮助吗?

解决方案

可以使用 SearchBuf 功能用[ soWholeWord]选项。

function SearchBuf(Buf: PAnsiChar; BufLen: Integer; SelStart: Integer; SelLength: Integer; SearchString: AnsiString; Options: TStringSearchOptions): PAnsiChar;

请参阅本示例

function ExistWordInString(aString:PWideChar;aSearchString:string;aSearchOptions: TStringSearchOptions): Boolean;
var
  Size : Integer;
Begin
      Size:=StrLen(aString);
      Result := SearchBuf(aString, Size, 0, 0, aSearchString, aSearchOptions)<>nil;
End;

使用这种方式

ExistWordInString('Go Delphi Go','Delphi',[soWholeWord,soDown]);

再见。

其他提示

只是因为Delphi的编辑器有一个“字匹配”功能,这并不意味着德尔福库提供了它!

通常,在大多数语言去这样做的方式是正则表达式。似乎他们(仍然)没有内置德尔福,因为有提供能力的第三方库。我发现的第一个例子是: HTTP://delphi.about的.com / OD / toppicks / TP / Delphi的-常规expressions.htm

通常,你会建立一个正则表达式类似

myRegex = '[' + Delim + ']+' + Word + '[' + Delim + ']+';
if regexSearch (Str, myRegex) then ...

您会想从你的库的文档获取详细信息。我的例子不能正确处理该单词的情况下,开始于海峡的开始或在它的端部结束,或者是所有STR的。

此功能不正是你需要的,但它是非常接近:

我希望是有用:

{ Copy all whole words from MainStr. The result will not have more than MaxChars characters. }

function CopyWords(MainStr: string; MaxChars: Integer): string;   
VAR EndsInSpace: Boolean;
    EndString, i: Integer;
    NextChar: char;
begin
 Assert(MaxChars > 0);
 EndString:= MaxChars;

 if Length(MainStr) > MaxChars then
  begin
   NextChar:= mainstr[MaxChars+1];

   if (MainStr[MaxChars] <> ' ') AND (NextChar <> ' ')
   then
     begin
      for i:= MaxChars downto 1 DO
       if MainStr[i]= ' ' then
        begin
         EndString:= i;
         Break;
        end
     end
   else
    if (MainStr[MaxChars]  = ' ')
    OR (MainStr[MaxChars] <> ' ') AND (NextChar = ' ')
    then EndString:= MaxChars;
  end;

 Result:= CopyTo(MainStr, 1, EndString);
 Result:= TrimRight(Result);
end;

如果你有象下面功能

function ExistWordInString(aString:PWideChar;aSearchString:string;aSearchOptions: TStringSearchOptions): Boolean;
var
  Size : Integer;
Begin
      Size:=StrLen(aString);
      Result := SearchBuf(aString, Size, 0, 0, aSearchString, aSearchOptions)<>nil;
End;

和调用它是这样的:

ExistWordInString('Go Delphi Go','Delphi',[soWholeWord,soDown]);

如果你调用一次你可能不会下跌的任何问题。但是,如果你把这种在一个循环中(例如1000倍或更多)首先使用名次函数(如下面)将令人惊讶地给你额外的性能

function ExistWordInString(const AString:string;const ASearchString:string;ASearchOptions: TStringSearchOptions): Boolean;
var
  Size : Integer;
  AWChar: PWideChar;
begin
   if Pos(LowerCase(ASearchString), LowerCase(AString)) = 0 then
   begin
      Exit(False);
   end;

   AWChar := PWideChar(AString);
   Size:=StrLen(AWChar);
   Result := SearchBuf(AWChar, Size, 0, 0, ASearchString, ASearchOptions)<>nil;
end;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top