C'è un efficiente Parola intera Funzione di ricerca in Delphi?
Domanda
In Delphi 2009 o successivo (Unicode), ci sono tutte le funzioni built-in o piccole routine scritte da qualche parte che farà una ricerca parola intera ragionevolmente efficiente in cui si forniscono i delimitatori che definiscono la parola, per esempio:.
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;
dove:
Word: string; { is the Unicode string to search for }
Str: string; { is the Unicode string to be searched }
Ho solo bisogno di questo per restituire un valore vero o falso, se la "Parola" è nella stringa.
Ci deve essere qualcosa per questo da qualche parte, perché lo standard di dialogo Trova è "Solo parola", come uno dei suoi opzioni.
Come è normalmente (o migliore) implementato?
Conclusione:
La risposta di RRUZ era perfetto. La routine SearchBuf era proprio quello che mi serviva. Posso anche andare nella routine StrUtils, estrarre il codice e modificarlo per soddisfare le mie esigenze.
Sono stato sorpreso di scoprire che SearchBuf non lo fa prima ricerca per la parola e poi verificare la presenza di delimitatori. Invece passa attraverso i caratteri della stringa, uno alla volta alla ricerca di un delimitatore. Se ne trova uno, allora verifichi la stringa e un altro delimitatore. Se non lo trova, sembra quindi per un altro delimitatore. Per l'amor di efficienza, che è molto intelligente!
Soluzione
È possibile utilizzare il href="http://docwiki.embarcadero.com/Libraries/XE2/en/System.StrUtils.SearchBuf" rel="nofollow noreferrer"> SearchBuf funzione
Vedere questo esempio Utilizzare questo modo Ciao. 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]);
Altri suggerimenti
Solo perché redattore di Delphi ha una funzione di "parola match", questo non significa che la libreria di Delphi lo offre!
In genere, nella maggior parte delle lingue la strada da percorrere per questo è un'espressione regolare. Sembra che siano (ancora) non integrato in Delphi, in quanto vi sono librerie 3a parte che offre la capacità. Il primo esempio che ho trovato è: http: //delphi.about .com / od / toppicks / tp / Delphi-regular-expressions.htm .
In genere, devi costruire un'espressione regolare qualcosa come
myRegex = '[' + Delim + ']+' + Word + '[' + Delim + ']+';
if regexSearch (Str, myRegex) then ...
Ti consigliamo di ottenere dettagli dalla documentazione della biblioteca che si ottiene. Il mio esempio non gestisce correttamente il caso della parola a partire dall'inizio di Str o termina alla sua fine, o di essere tutti Str.
Questa funzione non è esattamente ciò che serve, ma è abbastanza vicino:
Spero che sia utile:
{ 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;
Se si dispone di funzione come di seguito
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;
e chiamare in questo modo:
ExistWordInString('Go Delphi Go','Delphi',[soWholeWord,soDown]);
E 'vietato abbattere alcun problema se si chiama una volta. Ma se si chiama questo in un ciclo (ad esempio 1000 volte o più) prima di utilizzare la funzione Pos (come sotto) sorprendentemente dare una performance migliore
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;