Pregunta

En Delphi 2009 o posterior (Unicode), ¿existen funciones incorporadas o pequeñas rutinas escritas en alguna parte que va a hacer un razonablemente eficiente búsqueda de la palabra entera en que proporciona los delimitadores que definen la palabra, por ejemplo:.

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;

donde:

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

Yo sólo necesito esto para devolver un valor verdadero o falso si la "Palabra" se encuentra en la cadena.

Tiene que haber algo de esto en alguna parte, porque el estándar de diálogo Encontrar ha "coincidir sólo palabras completas" como una de sus opciones de.

¿Cómo es esto normalmente (o mejor) implementado?


Conclusión:

La respuesta de RRUZ era perfecto. La rutina SearchBuf era justo lo que necesitaba. Incluso puedo entrar en la rutina StrUtils, extraer el código y modificarlo para satisfacer mis necesidades.

Me sorprendió al descubrir que no lo hace SearchBuf primera búsqueda de la palabra y luego comprobar si hay delimitadores. En su lugar, pasa a través de los caracteres de la cadena de uno en uno en busca de un delimitador. Si lo encuentra, entonces compruebe la serie y otro delimitador. Si no lo encuentra, entonces busca otro delimitador. Por razones de eficacia, eso es muy inteligente!

¿Fue útil?

Solución

Puede utilizar la función de SearchBuf con el [ soWholeWord] opción.

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

Vea este ejemplo

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;

Utilice esta manera

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

adiós.

Otros consejos

El hecho de que el editor de Delphi tiene una función de "coincidencia de palabras", eso no significa que la biblioteca Delphi ofrece él!

Por lo general, en la mayoría de idiomas el camino a seguir para esto es una expresión regular. Parece que son (todavía) no integrado en Delphi, ya que hay bibliotecas 3 ª parte que ofrecen la capacidad. El primer ejemplo que he encontrado es: http: //delphi.about .com / OD / toppicks / tp / delphi-regular-expressions.htm .

Por lo general, usted construye una expresión regular como algo

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

querrá obtener detalles de la documentación de la biblioteca que se obtiene. Mi ejemplo no controla correctamente el caso de la palabra empezando por el principio o el final de Str en su extremo, o si todas Str.

Esta función no es exactamente lo que necesita, pero está bastante cerca:

Espero que sea útil:

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

Si tiene la función, como a continuación

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;

y lo llaman así:

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

Es posible que no cayó ningún problema si se llama una vez. Pero si se llama a esto en un bucle (por ejemplo, 1000 veces o más) primero usando la función Pos (como abajo) sorprendentemente le dará la capacidad

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;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top