AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi PosExUltra - Ultimative Stringsuche/Parser

PosExUltra - Ultimative Stringsuche/Parser

Ein Thema von Novo · begonnen am 21. Feb 2010 · letzter Beitrag vom 19. Mai 2010
Antwort Antwort
Seite 1 von 5  1 23     Letzte » 
Novo

Registriert seit: 27. Mai 2007
122 Beiträge
 
Delphi 7 Enterprise
 
#1

PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:19
Wenn ihr schon immer mal eine Funktion gebraucht habt, die euch Webseiten und große Texte parsen/filtern/auslesen kann,
OHNE dass ihr ewig euch mit Pos und PosEx rumärgern müsst, dann hat eure Suche ein Ende!

PS:
Für Verbesserungen, optimierungen wären wir sehr Dankbar!

Delphi-Quellcode:
{
* --------------------------------------------------------------------------------------
* "THE BEER-WARE LICENSE"
* YaNNiC und Novo schrieben diese Datei. Solange Sie diesen Vermerk nicht entfernen,
* können Sie mit der Datei machen, was Sie möchten. Wenn wir uns eines Tages treffen
* und Sie denken, die Datei ist es wert, können Sie mir dafür ein Bier ausgeben.
* Wir hatten auf jeden Fall genug davon, als wir diese Funktion geschrieben haben :D
* --------------------------------------------------------------------------------------
}


procedure PosExUltra(source, searchwordbefore, searchwordafter, addbefore, addafter: string; continuesearch, reversesearch: boolean; liste: Tstringlist);
var
  Anfang, Ende, Posi: Integer;
  Ergebnis: string;
begin
  if reversesearch then
  begin //if reversesearch = true:
    if continuesearch then
    begin //if continuesearch = true:
      Ende := 0;
      while PosEx(searchwordafter, source, ende) > 0 do
      begin
        Anfang := PosEX(searchwordafter, source, Ende);
        Posi := Anfang;
        if Anfang > 0 then
        begin
          while (PosEX(searchwordbefore, source, Posi) = 0) or (PosEX(searchwordbefore, source, Posi) > Posi) do
          begin
            Dec(Posi);
          end;
          Ergebnis := Copy(source, Posi + length(searchwordbefore), Anfang - (Posi + length(searchwordbefore)));
          if (Ergebnis <> '') or (Ergebnis <> ' ') then liste.Add(addbefore + Ergebnis + addafter);
          Ende := Posi + length(searchwordbefore) + Length(Ergebnis) + Length(searchwordafter);
        end;
      end;
    end
    else //if continuesearch = false:
    begin
      Ende := 0;
      Anfang := PosEX(searchwordafter, source, Ende);
      Posi := Anfang;
      if Anfang > 0 then
      begin
        while (PosEX(searchwordbefore, source, Posi) = 0) or (PosEX(searchwordbefore, source, Posi) > Posi) do
        begin
          Dec(Posi);
        end;
        Ergebnis := Copy(source, Posi + length(searchwordbefore), Anfang - (Posi + length(searchwordbefore)));
        if (Ergebnis <> '') or (Ergebnis <> ' ') then liste.Add(addbefore + Ergebnis + addafter);
      end;
    end;
  end
  else //if reversesearch = false:
  begin
    if continuesearch then
    begin //if continuesearch = true:
      Ende := 0;
      Anfang := PosEX(searchwordbefore, source, Ende);
      while Anfang > 0 do
      begin
        Anfang := PosEX(searchwordbefore, source, Ende);
        if Anfang > 0 then
        begin
          Ende := PosEX(searchwordafter, source, Anfang);
          Ergebnis := Copy(source, Anfang + length(searchwordbefore), (Ende - Anfang) - length(searchwordbefore));
          if (Ergebnis <> '') or (Ergebnis <> ' ') then liste.Add(addbefore + Ergebnis + addafter);
          Anfang := Anfang + length(Ergebnis);
        end;
      end;
    end
    else //if continuesearch = false:
    begin
      Ende := 0;
      Anfang := PosEX(searchwordbefore, source, Ende);
      if Anfang > 0 then
      begin
        Ende := PosEX(searchwordafter, source, Anfang);
        Ergebnis := Copy(source, Anfang + length(searchwordbefore), (Ende - Anfang) - length(searchwordbefore));
        if (Ergebnis <> '') or (Ergebnis <> ' ') then liste.Add(addbefore + Ergebnis + addafter);
      end;
    end;
  end;
end;
Erklärung:
Code:
procedure PosExUltra(source, searchwordbefore, searchwordafter, addbefore, addafter: string; continuesearch, reversesearch: boolean; liste: Tstringlist);

In "source" befindet sich der große Text, den man Filtern möchte.
"searchwordbefore" ist der Text, der sich VOR dem Wort was man will befindet.
"searchwordafter" ist der Text, der sich NACH dem Wort was man will befindet.
"addbefore" ist der Text, den man alternativ VOR dem GEFUNDENEN Wort anhängt.
"addafter" ist der Text, den man alternativ NACH dem GEFUNDENEN Wort anhängt.
"continuesearch": Es durchsucht den gesamten Text, wenn es MEHRERE Ergebnisse gibt (z.B. ALLE URLS),
bei False bricht es nach dem 1. Fund ab.
"reversesearch": Wenn "searchwordbefore" zu klein oder zu allgemein (zu oft vorkommend, oder gar variabel ist),
dann sucht es erst nach "searchwordafter" und geht dann rückwärts, bis er "searchwordbefore" gefunden hat.
Bsp: <ID=20>TEXT1<hierimmergleich> <ID=25>TEXT2<hierimmergleich> <ID=30>TEXT3<hierimmergleich> und man möchte alle!
How To Use:
Delphi-Quellcode:
  uses ... StrUtils;

  public
    stringlist: TStringList;

---

  stringlist := TStringList.Create;
  source := 'groooßer Text mit Inhalt was ich will';

  // wahlweise Absätze und Leerzeichen entfernen, um ein Besseres Ergenbis zu bekommen oder
  // weiteren Text zur Filterung zu erhalten:
  //source := StringReplace(source, ''#$A'', '', [rfReplaceAll]);
  //source := StringReplace(source, ''#13'', '', [rfReplaceAll]);
  //source := StringReplace(source, ' ', '', [rfReplaceAll]);

                                          //continue, reverse
  PosExUltra(source, 'VORDEMTEXT', 'NACHDEMTEXT', '', '', true, false, stringlist);
  
  stringlist.free;
Beispiele:

Einfache Vorwärtssuche bei eindeutigen Worten:
Delphi-Quellcode:
source := '<text>DASWILLICH</text>';
PosExUltra(source, '<text>', '</text>', '', '', true, false, stringlist);
//Suchwörter für Anfang und Ende sind leicht Filterbar, man kann vorwärts suchen.
Man möchte alle URL Links, die mit .com aufhören haben:
Delphi-Quellcode:
source := 'blatext xD [url]http://imagexxx.com[/url] und weiter text';
PosExUltra(source, 'http://', '.com', 'http://', '.com', true, false, stringlist);
//Suchwörter für Anfang und Ende sind leicht Filterbar, man kann vorwärts suchen.
//Da "http://" und ".com" abgeschnitten werden, fügen wir das dem gefundenen Wort nacher wieder an.
Schwierige Stelle zum Suchen: Die Rückwärtssuche!

Nehmen wir an, der Text wäre:
Code:
source :=
<td>[url="?content=dictionary&amp;task=term&amp;dir=bla&amp;ID=456"]DASWILLICH[/url]</td>
      <td style="line-height: 6pt;">
Der Anfangs und End Suchwert wäre:
Anfang: '">'
Ende: '</a></td>'
Das würde nicht funktionieren, da Anfang SEHR häufig vorkommt.
Also geht man zuerst so vor:

Delphi-Quellcode:
source := StringReplace(source, ''#$A'', '', [rfReplaceAll]);
source := StringReplace(source, ''#13'', '', [rfReplaceAll]);
source := StringReplace(source, ' ', '', [rfReplaceAll]);
Das würde dann so aussehen:
Code:
source := <td>[url="?content=dictionary&amp;task=term&amp;dir=bla&amp;ID=456"]DASWILLICH[/url]</td><tdstyle="line-height:6pt;">
nun kann man einfach die Rückwärtssuche bemühen, sie sucht zuerst nach Ende, und geht dann rückwärts bis er Anfang findet:

Delphi-Quellcode:
source := '<td>[url="?content=dictionary&amp;task=term&amp;dir=bla&amp;ID=456"]DASWILLICH[/url]</td><tdstyle="line-height:6pt;">';
PosExUltra(source, '">', '</a></td><tdstyle="line-height:6pt', '', '', true, true, stringlist);


Mfg Novo
Takeo
Don't make me angry...
You wouldn't like me when I'm angry!
Blut ist leben, Leben ist Blut, ins Licht geboren suchen wir die Dunkelheit!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.108 Beiträge
 
Delphi 12 Athens
 
#2

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:32
Sowas wie
if reversesearch = true then bitte durch
if reversesearch then ersetzen (die Gründe wurden schon oft im Forum erwähnt)

Und der Name ist definitiv verwirrend, denn gesucht wird hier nix, also nicht entsprechend des Funktionsergebnisses.
StringReplaceUltra wäre da schon besser.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Novo

Registriert seit: 27. Mai 2007
122 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:37
Zitat von himitsu:
Sowas wie
if reversesearch = true then bitte durch
if reversesearch then ersetzen (die Gründe wurden schon oft im Forum erwähnt)
Was ist denn der Grund?

Zitat von himitsu:
Und der Name ist definitiv verwirrend, dann ggesucht wird hier nix, also nicht entsprechend des Funktionsergebnisses.
StringReplaceUltra wäre da schon besser.
Hm?
Klar wird hier gesucht!
ist sozusagen eine bessere PosEx -> PosExUltra
Takeo
Don't make me angry...
You wouldn't like me when I'm angry!
Blut ist leben, Leben ist Blut, ins Licht geboren suchen wir die Dunkelheit!
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:40
Jupp, "StringReplace" wäre falsch. Es wird zwar nicht die Position zurückgegeben (also doch eher kein "PosEx"), aber es wird gesucht.

Zitat von Novo:
Was ist denn der Grund?
Über den Umgang mit Boolean

Deine Funktion sieht viel versprechend aus bzw. was sie alles kann. Kannst du etwas über die Performance sagen, da du schreibst, sie sei für große Texte geeignet?
Es gibt zahlreiche, schnelle Suchalgorithmen (Rabin-Karp & Co.), aber du verwendest keinen davon, wenn ich das richtig sehe.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:43
Das ist eine nette Funktion. Nenne sie doch lieber
Function PosEierlegendeWollmilchSau Der Zusatz 'Ultra' erinnert so an Waschmittel.

Im Ernst: Was kann die Funktion, was ein TRegExpr nicht kann?
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Novo

Registriert seit: 27. Mai 2007
122 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:45
Zitat von Matze:
Deine Funktion sieht viel versprechend aus bzw. was sie alles kann. Kannst du etwas über die Performance sagen, da du schreibst, sie sei für große Texte geeignet?
Es gibt zahlreiche, schnelle Suchalgorithmen (Rabin-Karp & Co.), aber du verwendest keinen davon, wenn ich das richtig sehe.
Nunja die Performance hängt ganz nach dem Aufbau der suchquelle ab, ob du vorwärts oder Rückwärts suchen musst, und natürlich auch wie viele Zeichen dein searchwordbefore und searchwordafter hat.

Ein Beispiel:

http://dict-navi.com/api.php
800 Wörter -> Vorwärts -> SAUSCHNELL
( ja ich weis ist XML, dazu gibts ne XML Komponente, die bekomm ich aber partout nicht zum laufen FAIL )

http://dict-navi.com/?content=dictio...=list&type=all
Das gleiche mit ebenfalls 800 Wörter -> Rückwärtssuche nötig -> 30 Sekunden lang 25% CPU auslastung

Sind aber schon heftig viele Zeilen.

Wenn man z.B. Quellcode von Youtube parst, um die Video ID zu finden, ist das ruckzuck!


Zitat von alzaimar:
Im Ernst: Was kann die Funktion, was ein TRegExpr nicht kann?
ähm z.B. das einfache und komfortable universelle einsetzen, OHNE Regular Expression Regeln zu kennen?
Takeo
Don't make me angry...
You wouldn't like me when I'm angry!
Blut ist leben, Leben ist Blut, ins Licht geboren suchen wir die Dunkelheit!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.108 Beiträge
 
Delphi 12 Athens
 
#7

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:52
Ich hätte aer noch was:
Application.ProcessMessages; Dieses hat in soeiner Funktion besser nichts drin zu suchen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Novo

Registriert seit: 27. Mai 2007
122 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:53
Zitat von himitsu:
Ich hätte aer noch was:
Application.ProcessMessages; Dieses hat in soeiner Funktion besser nichts drin zu suchen.
ok dann mach ich sie raus, aber dann freezed halt bei großen Texten solang die Form, das ist auch nicht schön.
Takeo
Don't make me angry...
You wouldn't like me when I'm angry!
Blut ist leben, Leben ist Blut, ins Licht geboren suchen wir die Dunkelheit!
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 15:56
Zitat von Novo:
ok dann mach ich sie raus, aber dann freezed halt bei großen Texten solang die Form, das ist auch nicht schön.
Die sauberere Lösung wäre in dem Fall eh, die Funktion in einem zweiten Thread auszuführen.
  Mit Zitat antworten Zitat
Novo

Registriert seit: 27. Mai 2007
122 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: PosExUltra - Ultimative Stringsuche/Parser

  Alt 21. Feb 2010, 16:00
Zitat von NamenLozer:
Die sauberere Lösung wäre in dem Fall eh, die Funktion in einem zweiten Thread auszuführen.
Das einzige, was ich je Threaded gemacht habe, war ein idhhttp.get
Mal schaun, ob das denn funktioniert, bin mal weiter am Rumbasteln.
Falls du es schon kannst, codeschnipsel
Takeo
Don't make me angry...
You wouldn't like me when I'm angry!
Blut ist leben, Leben ist Blut, ins Licht geboren suchen wir die Dunkelheit!
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:51 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