2010-11-20 15 views

Respuesta

3
function TForm1.FindText(const aPatternToFind: String):Boolean; 
    var 
    p: Integer; 
    begin 
    p := pos(aPatternToFind, Memo1.Text); 
    Result := (p > 0); 
    if Result then 
     begin 
     Memo1.SelStart := p; 
     Memo1.SelLength := Length(aPatternToFind); 
     Memo1.SetFocus; // necessary so highlight is visible 
     end; 
    end; 

Esto NO busca entre líneas si WordWrap es verdadero.

+0

búsqueda en '' TStrings.Text' en lugar de TStrings.Strings' es muy caro. 2 × N en el hecho. –

+0

@ user205376 - ¿Por qué dices eso? TStrings.Text es una cadena única en la que creo que pos() sería rápido. Buscando, como sugiere, TStrings.Strings involucraría subíndices para acceder a cada cadena. Eso, IMO, opinión, sería más lento y no proporcionaría ninguna funcionalidad adicional que el pos() no. (Y, requeriría algún código complicado para resaltar el patrón encontrado) ¿Por qué crees que no? – RobertFrank

+0

Un poco tarde para el juego, pero para lo anterior, depende de la implementación. Después de todo, TStrings es abstracto. Memo.Lines.Text (= TMemoStrings.Text) obtiene el texto de la nota mediante una única llamada a la API, mientras que una cadena de tiendas TStringList independiente y TStringList.Text las combina en una sola cadena en cada solicitud (que a menudo es aún más rápido que llamar la API, por cierto). La respuesta utiliza Memo1.Text, que creo que pasa por alto cualquier descendiente de TStrings y llama directamente a alguna api de GetText en el manejador de la nota. – GolezTrol

11

Esta búsqueda permite la envoltura documento, la caja (en) búsqueda sensible y búsqueda de la posición del cursor.

type 
    TSearchOption = (soIgnoreCase, soFromStart, soWrap); 
    TSearchOptions = set of TSearchOption; 


function SearchText(
    Control: TCustomEdit; 
    Search: string; 
    SearchOptions: TSearchOptions): Boolean; 
var 
    Text: string; 
    Index: Integer; 
begin 
    if soIgnoreCase in SearchOptions then 
    begin 
    Search := UpperCase(Search); 
    Text := UpperCase(Control.Text); 
    end 
    else 
    Text := Control.Text; 

    Index := 0; 
    if not (soFromStart in SearchOptions) then 
    Index := PosEx(Search, Text, 
     Control.SelStart + Control.SelLength + 1); 

    if (Index = 0) and 
     ((soFromStart in SearchOptions) or 
     (soWrap in SearchOptions)) then 
    Index := PosEx(Search, Text, 1); 

    Result := Index > 0; 
    if Result then 
    begin 
    Control.SelStart := Index - 1; 
    Control.SelLength := Length(Search); 
    end; 
end; 

Puede establecer HideSelection = False en la nota para mostrar la selección incluso si la nota no está enfocada.

uso como esto:

SearchText(Memo1, Edit1.Text, []); 

permite la búsqueda ediciones también.

+0

El uso de UpperCase podría no darle los resultados deseados, p. en francés, los caracteres en mayúscula no pueden no tener acento, mientras que los caracteres en minúscula puede tener uno (que es diferente del francés canadiense Creo que, en mayúsculas también pueden ser acentuados). Entonces, en este caso, usar LowerCase daría mejores resultados. – dummzeuch

+0

Bueno, la letra acentuada y la letra sin acentos son dos letras diferentes, ¿verdad? Una palabra francesa, cuando se convierte a UpperCase se mostrará como PRIVE, en minúsculas sería privé. Por otro lado, la letra mayúscula É tampoco se convierte en é, por lo que no veo cómo afectará eso a los resultados de búsqueda. Aunque debo admitir que estoy probando esto en Delphi 7. Si Unicode o el posible uso de las opciones de localización en sus rendimientos Delphi en mejores resultados cuando se utiliza minúsculas, por favor. – GolezTrol

+2

GolezTrol: ¡gracias por el consejo de HideSelection! – RobertFrank

Cuestiones relacionadas