Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi PosEx gibt immer 0 ( Null ) zurück (https://www.delphipraxis.net/131497-posex-gibt-immer-0-null-zurueck.html)

TheMiller 25. Mär 2009 21:28


PosEx gibt immer 0 ( Null ) zurück
 
Hallo Delphi-Freunde!

Ich möchte einen Text aus einem RichEdit auf das Vorkommen bestimmter Worte durchsuchen und diese dann rot markieren. Letzteres funktioniert.

Ich arbeite mit PosEx (das erste Mal), nachdem ich erkennen musste, dass mein geliebtes Pos immer nur das erste Vorkommen findet.

Doch PosEx gibt immer nur 0 zurück, obwohl ich den Code aus diesem Forum habe. Hier mal mein Code:

Delphi-Quellcode:
i:=0;
        while PosEx('mit', 'mit mama und mit papa fahre ich mit', i) > 0 do
        begin
          ShowMessage('gefunden');
          with (re) do
          begin
            SelStart:=i;
            SelLength:=Length('mit');
            SelAttributes.Color:=clRed;
            SelLength:=0;
          end;
          i:=PosEx('mit', 'mit mama und mit papa fahre ich mit', i)+1;
        end;
Was ist daran denn falsch? Noch nichteinmal kommen die ShowMessages...

Danke im Voraus

Matze 25. Mär 2009 21:33

Re: PosEx gibt immer 0 ( Null ) zurück
 
Hallo,

da das erste Zeichen eines Strings den Index 1 besitzt, vermute ich, dass du auch bei 1 und nicht bei 0 starten musst.

Grüße, Matze

jaenicke 25. Mär 2009 21:35

Re: PosEx gibt immer 0 ( Null ) zurück
 
Du suchst nicht im RichEdit sondern in deinem eigenen String 'mit mama und mit papa fahre ich mit', was soll das bringen?

// EDIT:
Ja, i muss natürlich 1 am Anfang sein, stimmt.

// EDIT2:
Wie wäre es so, so klappt es:
Delphi-Quellcode:
var
  i: Integer;
begin
  i := PosEx('mit', RichEdit1.Text, 1);
  while i > 0 do
  begin
    ShowMessage('gefunden');
    RichEdit1.SelStart := i - 1;
    RichEdit1.SelLength := Length('mit');
    RichEdit1.SelAttributes.Color := clRed;
    RichEdit1.SelLength := 0;
    i := PosEx('mit', RichEdit1.Text, i + 1);
  end;

himitsu 25. Mär 2009 22:56

Re: PosEx gibt immer 0 ( Null ) zurück
 
ich weiß, manchmal bin ich etwas brutal, aber wozu muß man unbedingt PosEx doppelt haben :angel2:

und RichEdit1.Text vielleicht nicht ständig neu auslesen.

soll hier immer nur das aktuelle markiert werden, dann
Delphi-Quellcode:
S := RichEdit1.Text;
i := 0;
while true do
begin
  i := PosEx('mit', S, i + 1);
  if i = 0 then break;
  RichEdit1.SelStart := i - 1;
  RichEdit1.SelLength := Length('mit');
  RichEdit1.SelAttributes.Color := clRed;
  ShowMessage('gefunden');
  RichEdit1.SelAttributes.Color := clBlack;
  RichEdit1.SelLength := 0;
end;
ansonsten
Delphi-Quellcode:
S := RichEdit1.Text;
B := False;
i := 0;
while true do
begin
  i := PosEx('mit', S, i + 1);
  if i = 0 then break;
  RichEdit1.SelStart := i - 1;
  RichEdit1.SelLength := Length('mit');
  RichEdit1.SelAttributes.Color := clRed;
  B := True;
end;
if B then ShowMessage('gefunden');

TheMiller 25. Mär 2009 23:50

Re: PosEx gibt immer 0 ( Null ) zurück
 
Danke für eure Hilfe und Quelltexte. Es lag atsächlich an i:=0. Ist ja auch logisch.

Was den doppelten Aufruf von PosEx angeht hast du Recht. Das werde ich noch entsprechend ändern.

Danke!

blablab 26. Mär 2009 05:25

Re: PosEx gibt immer 0 ( Null ) zurück
 
Daraus lernen wir, dass man besonders vorsichtig sein muss beim PosEx :zwinker:

Blup 26. Mär 2009 16:07

Re: PosEx gibt immer 0 ( Null ) zurück
 
PosEx hat zumindest bis Delphi 5 durchaus mit Paramter 0 als Index funktioniert, wurde in einer späteren Delphiversion verändert.

Im zweiten Beispiel von himitsu wird i mit 1 initialisiert, muss an dieser Stelle richtig 0 sein (gesucht wird ab i + 1).

Hier noch meine (hübschere :wink: ) Variante:
Delphi-Quellcode:
function Markiere(ARichedit: TRichEdit; AText: String; AColor: TColor): Boolean;
{---}
  function FindNext(const AValue, AText: String; var AIndex: Integer): Boolean; inline;
  begin
    AIndex := PosEx(AValue, AText, AIndex);
    Result := (AIndex > 0);
  end;
{---}
var
  s: String;
  i: Integer;
begin
  Result := False;
  s := ARichEdit.Text;
  i := 1;
  while FindNext(AText, s, i) do
  begin
    ARichEdit.SelStart           := i - 1;
    ARichEdit.SelLength          := Length(AText);
    ARichEdit.SelAttributes.Color := AColor;
    Inc(i, Length(AText));
    Result := True;
  end;
end;

if Markiere(Richedit1, 'mit', clRed) then
  ShowMessage('gefunden');

SubData 26. Mär 2009 17:11

Re: PosEx gibt immer 0 ( Null ) zurück
 
War bei Delphi 5 dann der Index des ersten Zeichens 0 oder 1?
Oder hat PosEx einfach nur den "Anfangswert" 0 akzeptiert?

himitsu 26. Mär 2009 17:20

Re: PosEx gibt immer 0 ( Null ) zurück
 
In Delphi war der 1. Zeichen-Index, bei Strings, schon immer 1.

Lag daran, daß beim 1. String-Typ, dem heute sogenannten ShortString, der Index 0 schon belegt ist (mit dem Längen-Byte)
und dieses bis jetzt, aus Kompatibilitätsgründen, so beibehalten wurde. :angel2:

Christian Seehase 26. Mär 2009 18:49

Re: PosEx gibt immer 0 ( Null ) zurück
 
Moin Zusammen,

einen kleinen Hinweis hätte ich noch.
Die Versionen von Himitsu und Blup haben den grossen Vorteil, dass sie nur einmal auf RichEdit.Text zugreifen, was einen erheblichen Performancegewinn bringen kann. Der Gewinn ist umso grösser, je mehr Daten das RichEdit enthält, da die Eigenschaft Text bei jedem Zugriff aus den Lines aufgebaut wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:33 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz