Есть ли эффективная функция поиска всего слова в Delphi?

в Delphi 2009 или более поздней версии (Unicode) есть ли встроенные функции или небольшие подпрограммы, написанные где-то, которые будут выполнять достаточно эффективный поиск всего слова, где вы предоставляете разделители, определяющие слово, например:

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

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

где:

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

мне нужно только это, чтобы вернуть значение true или false, если "слово" находится в строке.

должно быть что-то для этого где-то, потому что стандартный диалог поиска имеет "только целое слово" как один из вариантов.

Как это обычно (или лучше всего) реализуется?


вывод:

ответ РРУЗ был идеальным. В SearchBuf рутины, что мне было нужно. Я даже могу войти в процедуру StrUtils, извлечь код и изменить его в соответствии с моими требованиями.

Я был удивлен, обнаружив, что SearchBuf сначала не ищет слово, а затем проверяет наличие разделителей. Вместо этого он проходит через символы строки по одному за раз ищу разделитель. Если он находит один, то он проверяет строку и другой разделитель. Если он не находит его, он ищет другой разделитель. Ради эффективности, это очень умно!

4 ответов


можно использовать 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 имеет функцию "совпадение слов", это не означает, что библиотека Delphi предлагает его!

обычно в большинстве языков для этого используется регулярное выражение. Кажется, они (все еще) не встроены в Delphi, так как есть сторонние библиотеки, предлагающие эту возможность. Первый пример, который я нашел:http://delphi.about.com/od/toppicks/tp/delphi-regular-expressions.htm .

обычно вы создаете регулярное выражение что-то вроде

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

вы хотите получить подробную информацию из документации библиотеки, которую вы получаете. Мой пример неправильно обрабатывает случай слова, начинающегося в начале Str или заканчивающегося в его конце, или являющегося всем 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 раз или более), сначала используя функцию Pos (как показано ниже), удивительно даст вам дополнительную производительность

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;