Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi PosExUltra - Ultimative Stringsuche/Parser (https://www.delphipraxis.net/148055-posexultra-ultimative-stringsuche-parser.html)

Novo 23. Feb 2010 09:47

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Zitat:

Zitat von omata
Ups, ja ihr habt recht, danke für die Hinweise.
Hier die Korrektur...

Ich bin schwer beeindruckt!
Bei deiner Suche klappt sogar eine Suche nach:
Delphi-Quellcode:
">
und:
Delphi-Quellcode:
</a></td>
obwohl
Delphi-Quellcode:
">
SEHR häufig vorkommt.
Ausserdem scheint deine Funktion schneller zu sein, als meine, weniger Code ist es auf jedenfall.

Respekt und danke!


Mfg Novo

HeikoAdams 25. Feb 2010 09:51

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Gibt es einen bestimmten Grund, warum Du
Delphi-Quellcode:
procedure ExtractBetween(const aSource, aPrefix, aSuffix : string;
                         aFindAll : Boolean; aNewPrefix, aNewSuffix : string;
                         aWords : TStrings);
verwendest und nicht
Delphi-Quellcode:
procedure ExtractBetween(const aSource, aPrefix, aSuffix : string;
                         const aFindAll : Boolean; const aNewPrefix, aNewSuffix : string;
                         var aWords : TStrings);
?

Da bei keinem der Parameter eine Wertzuweisung stattfindet, kann man sie ohne Probleme auch alle als Konstanten deklarieren, mit Ausnahme vom aWords. Der muss als Var-Parameter deklariert werden, da ja dort die Ergebnisse gespeichert werden.

Man könnte das ganze auch noch eleganter mittels
Delphi-Quellcode:
procedure ExtractBetween(const aSource, aPrefix, aSuffix : string;
                         const aNewPrefix, aNewSuffix : string;
                         var aWords : TStrings; const aFindAll : Boolean = True);
umsezen. In diesem Fall bräuchte man aFindAll nur dann zu übergeben, wenn nur der erste Treffer zurückgegeben werden soll.

Um das ganze richtig elegant zu machen, würde ich das ganze so umbauen:
Delphi-Quellcode:
function ExtractBetween(const aSource, aPrefix, aSuffix, aNewPrefix, aNewSuffix : string;
                         const aFindAll : Boolean = True): TStrings;
var
  PrefixLength, PosPrefix, PosSuffix, BestPos : Integer;
begin
  PosPrefix := PosEx(aPrefix, aSource, 1);

  if (PosPrefix > 0) then
  begin
    PrefixLength := Length (aPrefix);

    repeat
      PosSuffix := PosEx(aSuffix, aSource, PosPrefix + PrefixLength);

      if (PosSuffix > 0) then
      begin
        while (PosPrefix <> 0) and (PosPrefix < PosSuffix) do
        begin
          BestPos := PosPrefix;
          PosPrefix := PosEx(aPrefix, aSource, PosPrefix + PrefixLength);
        end;

        Result.Append(
            aNewPrefix
          + Copy(aSource, BestPos + PrefixLength, PosSuffix-BestPos - PrefixLength)
          + aNewSuffix
        );
      end;
    until not aFindall or (PosSuffix = 0) or (PosPrefix = 0);
  end;
end;
dann kann man sich den Parameter aWords nämlich komplett sparen :wink:

Hawkeye219 25. Feb 2010 10:34

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Hallo Heiko,

Zitat:

Zitat von HeikoAdams
dann kann man sich den Parameter aWords nämlich komplett sparen :wink:

Und wer erzeugt die Stringliste dann? Wie möchtest du das Ergebnis beispielsweise einem Memo zuweisen? In solchen Fällen gibt es eine feste Regel, an die man sich halten sollte: Der Aufrufer muss eine Stringliste bereitstellen, die von der Routine gefüllt wird. Er ist es auch, der die Stringliste wieder freigeben muss. Jede andere Vorgehensweise wird früher oder später zu einem Problem führen.

Gruß Hawkeye

schlecki 25. Feb 2010 10:48

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Zitat:

Zitat von HeikoAdams
Delphi-Quellcode:
procedure ExtractBetween(const aSource, aPrefix, aSuffix : string;
                         const aFindAll : Boolean; const aNewPrefix, aNewSuffix : string;
                         var aWords : TStrings);
Da bei keinem der Parameter eine Wertzuweisung stattfindet, kann man sie ohne Probleme auch alle als Konstanten deklarieren, mit Ausnahme vom aWords. Der muss als Var-Parameter deklariert werden, da ja dort die Ergebnisse gespeichert werden.

Meiner Meinung nach, kann auch aWords als const deklariert werden. Du willst ja keine andere Liste zuweisen, sondern nur ihre Werte ändern. Das sollte auch so gehen.

DeddyH 25. Feb 2010 10:51

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Richtig. Ich selbst deklariere übergebene Objekte immer als const, damit ich mir nicht versehentlich "ins Knie schieße", indem ich die Referenz ändere.

xZise 25. Feb 2010 11:56

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Übrigens musst du bei Objektreferenzen kein var davor schreiben.
Du bekommst ja quasi einen Pointer auf die Stringliste und den änderst du ja nicht, also kein Grund für var ;) Und wie bereits gesagt wurde ist const sogar angebrachter.

MfG
Fabian

Novo 25. Feb 2010 17:33

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Zitat:

Zitat von HeikoAdams
Um das ganze richtig elegant zu machen, würde ich das ganze so umbauen:
Delphi-Quellcode:
function ExtractBetween(const aSource, aPrefix, aSuffix, aNewPrefix, aNewSuffix : string;
                         const aFindAll : Boolean = True): TStrings;
dann kann man sich den Parameter aWords nämlich komplett sparen :wink:

Keine gute idee, daraus ne funktion zu machen.
Ausserdem geht das nichtmal:
Delphi-Quellcode:
      ListBox1.Items.AddStrings(FuncExtractBetween(source, '[img]', '[/img]</img>', '', '', True));
Bei:
Code:
<img src="http://blub.de
" alt="album"></img>
<img src="http://blub.de
" alt="bild"></img>
<img src="http://blub.de
" alt="bild"></img>
<img src="http://blub.de
" alt="album"></img>
<img src="http://blub.de
" alt="album"></img>
<img src="http://blub.de
" alt="bild"></img>
<img src="http://blub.de
" alt="album"></img>
mal alle album links ziehn.
öhm und ist die rückwärtssuche nun wirklich überflüssig?

GPRSNerd 26. Feb 2010 08:57

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Jau, das mit der direkten Zuweisung der TStrings als Funktionsrückgabe funktioniert wirklich nicht.
Beim ersten Zugriff auf Results in der Funktion (z.B. durch Results.Beginupdate oder .Append) kommt eine Read/write access exception.
Weiss jemand, warum das nicht geht und ob es da einen Trick gibt?

DeddyH 26. Feb 2010 09:02

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Das dürfte daran liegen, dass Result nirgends erzeugt wird. Aber wie bereits weiter oben gesagt sollte man das Objekt besser an die Routine übergeben, sonst fängt man sich schnell ein Speicherleck ein.

xZise 26. Feb 2010 09:07

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Moin,
naja wo ist denn das Objekt erstellt worden? Vorgesehen war es eigentlich das dies außerhalb passiert, aber wenn die nun zurückgegeben wird, musst du es wohl in der Funktion erstellen. Allerdings gewöhne dir das lieber nicht an, weil das ist nicht gerade sauberer Stil.

Es stellt sich nämlich die Frage, wo wird das denn wieder freigegeben? Bei der ursprünglichen Version war das klar:
Delphi-Quellcode:
var
  o : TObject;
begin
  o := TObject.Create;
  try
    func(o);
    // do sth.
  finally
    o.Free;
  end;
Bei der veränderten Fassung, kannst du das nicht mehr so strikt trennen. Deshalb ist der Trick, nimm die Fassung von omata (oder?):
Delphi-Quellcode:
ExtractBetween(…, Memo.Lines);
Nebenbei, wenn der letzte Parameter ein var-Parameter wäre, geht das glaub ich nicht, weil TCustomMemo.Lines eine Property ist.

MfG
Fabian


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:37 Uhr.
Seite 3 von 5     123 45      

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