2009-11-05 89 views
5

德爾福2009年或更高版本(Unicode)的,有沒有內置函數或小程序的地方寫,會做一個合理高效的整個詞搜索,你提供定義這個詞的分隔符,如:德爾福有沒有一個有效的整詞搜索功能?

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不會先搜索該詞,然後檢查分隔符。相反,它一次遍歷字符串中的字符,尋找分隔符。如果它找到一個,那麼它檢查字符串和另一個分隔符。如果它沒有找到它,它會查找另一個分隔符。爲了提高效率,這非常聰明!

回答

13

您可以使用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]); 

再見。

+1

不錯!您現在將自己的解決方案發布在您自己的博客上,網址爲:http://theroadtodelphi.wordpress.com/2009/11/05,因爲我做了進一步的調查。感謝您提供的額外信息。 – lkessler 2009-11-06 04:54:48

+0

'ExistWordInString('Delphi','Delphi'[soWholeWord,soDown]);'失敗。查看[SearchBuf soWholeWord意外輸出](http://stackoverflow.com/q/25877986/576719)。 – 2014-09-16 21:12:35

2

僅僅因爲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的全部。

0

這個功能是不是你所需要的東西,但它是非常接近:

我希望它是有用的:

{ 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

如果你有功能類似下面

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]); 

如果你一次調用它,你可能不會遇到任何問題。但是,如果你使用Pos函數(如下圖)首先使用Pos函數(例如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;