Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is There An Efficient Whole Word Search Function in Delphi?

In Delphi 2009 or later (Unicode), are there any built-in functions or small routines written somewhere that will do a reasonably efficient whole word search where you provide the delimiters that define the word, 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;

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 a true or false value if the "Word" is in the string.

There must be something for this somewhere, because the standard Find Dialog has "Match whole word only" as one of it's options.

How is this normally (or best) implemented?


Conclusion:

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

I was surprised to find that SearchBuf doesn't first search for the word and then check for delimiters. Instead it goes through the characters of the string one at a time looking for a delimiter. If it finds one, then it checks for the string and another delimiter. If it doesn't find it, it then looks for another delimiter. For efficiency's sake, that's very smart!

like image 489
lkessler Avatar asked Nov 05 '09 05:11

lkessler


2 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 this way

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

Bye.

like image 137
RRUZ Avatar answered Oct 16 '22 21:10

RRUZ


Just because Delphi's editor has a "word match" function, that doesn't mean the Delphi library offers it!

Typically, in most languages the way to go for this is a regular expression. Seems they're (still) not built into Delphi, as there are 3rd party libraries offering the capability. The first example I found is: http://delphi.about.com/od/toppicks/tp/delphi-regular-expressions.htm .

Typically, you'd build a regular expression something like

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

You'll want to get details from the documentation of the library you get. My example doesn't correctly handle the case of the word starting at the beginning of Str or ending at its end, or being all of Str.

like image 26
Carl Smotricz Avatar answered Oct 16 '22 21:10

Carl Smotricz