Gibt es eine effektive Ganzwortsuche-Funktion in Delphi?
Frage
In Delphi 2009 oder später (Unicode), gibt es integrierte Funktionen oder kleine Routinen irgendwo geschrieben, dass eine einigermaßen effizient ganzes Wort-Suche, wo Sie die Trennzeichen zur Verfügung stellen, die das Wort definieren, z.
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;
Dabei gilt:
Word: string; { is the Unicode string to search for }
Str: string; { is the Unicode string to be searched }
Ich brauche nur diesen einen wahren oder falschen Wert zurück, wenn das „Wort“ in der Zeichenfolge ist.
Es gibt etwas für diesen irgendwo sein muss, weil die Standard-Suchdialog hat „ganzes Wort paßt nur“ als eine seiner Optionen.
Wie ist dies in der Regel (oder am besten) umgesetzt?
Fazit:
RRUZ Antwort war perfekt. Die SearchBuf Routine war genau das, was ich brauchte. Ich kann sogar in die StrUtils Routine gehen, extrahieren Sie den Code, und ändern Sie es meine Anforderungen passen.
Ich war überrascht, dass SearchBuf für das Wort nicht erster Such tut und dann für Begrenzer überprüfen. Stattdessen geht es durch die Zeichen der Zeichenfolge einen nach dem anderen für ein Trennzeichen suchen. Wenn es einen findet, dann überprüft es für die Zeichenfolge und ein anderes Trennzeichen. Wenn es es nicht findet, sucht es dann für ein anderes Trennzeichen. Aus Gründen der Effizienz willen, das ist sehr intelligent!
Lösung
Sie können das SearchBuf Funktion mit der [ soWholeWord] Option.
function SearchBuf(Buf: PAnsiChar; BufLen: Integer; SelStart: Integer; SelLength: Integer; SearchString: AnsiString; Options: TStringSearchOptions): PAnsiChar;
Sehen Sie dieses Beispiel
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;
Verwenden Sie es auf diese Weise
ExistWordInString('Go Delphi Go','Delphi',[soWholeWord,soDown]);
Bye.
Andere Tipps
Nur weil Delphi-Editor ein „Wortspiel“ -Funktion hat, bedeutet das nicht, die Delphi-Bibliothek bietet es!
Normalerweise in den meisten Sprachen der Weg für diese zu gehen, ist ein regulärer Ausdruck. Scheint sie (noch) nicht gebaut in Delphi ist, wie es 3rd-Party-Bibliotheken bieten die Fähigkeit ist. Das erste Beispiel, das ich gefunden ist: http: //delphi.about .com / od / toppicks / tp / delphi-regular-expressions.htm .
Normalerweise würde man einen regulären Ausdruck so etwas wie
bauenmyRegex = '[' + Delim + ']+' + Word + '[' + Delim + ']+';
if regexSearch (Str, myRegex) then ...
Sie wollen Details erhalten aus der Dokumentation der Bibliothek, die Sie erhalten. Mein Beispiel verarbeitet nicht korrekt den Fall des Wortes am Anfang Str beginnen oder an seinem Ende am Ende, oder alle Str sein.
Diese Funktion ist nicht genau das, was Sie brauchen, aber es ist ziemlich nah dran:
Ich hoffe, es ist nützlich:
{ 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;
Wenn Sie funktionieren wie unter
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;
und nennen Sie es wie folgt aus:
ExistWordInString('Go Delphi Go','Delphi',[soWholeWord,soDown]);
Sie fiel möglicherweise kein Problem, wenn man es einmal nennen. Aber wenn Sie diese in einer Schleife aufrufen (zB 1000-mal oder mehr) erste Pos-Funktion (wie unten) wird überraschenderweise geben Sie sich zusätzliche Leistung durch
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;