Is there an effective whole word search feature in Delphi?

In Delphi 2009 or later (Unicode), are there any built-in functions or small subroutines written somewhere that will do quite efficient whole word searches, where you provide delimiters that define that word, for example:

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; 

Where:

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

I only need this to return true or false if "Word" is in the string.

There must be something for this somewhere, because in the standard search dialog box there is “Match the whole word” only as one of its options.

How is this usually (or better) implemented?


Output:

RRUZ's answer was perfect. The SearchBuf procedure was exactly what I needed. I can even go into the StrUtils routine, extract the code and modify it according to my requirements.

I was surprised to find that SearchBuf does not search the word first, and then checks the delimiters. Instead, it goes through the string characters one at a time in search of a separator. If he finds one, then he checks the string and the other delimiter. If he does not find it, he searches for another delimiter. For efficiency, it is very smart!

+5
source share
4 answers

You can use the SearchBuf function with the [soWholeWord] option.

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

See this example.

 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; 

Use it that way

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

Bye

+13
source

Just because the Delphi editor has a “word matching” feature, this does not mean that the Delphi library offers it!

Typically, in most languages, the path to this is a regular expression. It seems that they are (still) not built into Delphi, as there are third-party libraries offering this feature. The first example I found is: http://delphi.about.com/od/toppicks/tp/delphi-regular-expressions.htm .

You will usually create a regular expression like

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

You want to receive detailed information from the library documentation that you will receive. In my example, the case of a word beginning at the beginning of Str or ending at the end, or all of Str, is not handled correctly.

+2
source

This function is not quite what you need, but it is pretty close:

Hope this is helpful:

 { 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; 
0
source

If you have a function as shown below

 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; 

and name it as follows:

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

You cannot run into any problem if you name it once. But if you call this in a loop (e.g. 1000 times or more), using the Pos function first (as shown below) will surprisingly give you extra performance

 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; 
0
source

All Articles