Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
16.05.2003, 21:19
feigling



Hoi,
also ich habe ein kleines Problem und zwar:
Ich möchte ein Programm machen, was mir aus einer Datei (txt-Datei) einen bestimmten Wert raussuchen soll, wenn man ein Keyword angibt.
Die Datei ist so aufgebaut:

Quellcode:"NUMMER1" "Nummer1, bla bla bla"
"NUMMER2" "Nummer2, bla bla bla"
und wenn man dann jetzt im Programm NUMMER1 angibt, dann gibt der als String - Nummer1, bla bla bla - aus. Nun habe ich mich also drangesetzt und versucht, sowas zu schreiben und was ich da gemacht habe, funzt auch, allerdings habe ich so das Gefühl, dass der Code sehr umständlich bzw bescheuert ist =)

Mein Code sieht folgendermaßen aus:

Quellcode:function TParseFile.file_read(keyword : string) : string;
var line : string;
begin
  while not eof(data) do
  begin
    readln(data, line);  // einlesen
    delete(line, 1, pos(#34, line));  // alles bis zum ersten " löschen
    if copy(line, 1, pos(#34, line) -1) = keyword then  // Keyword vergleichen
    begin
      delete(line, 1, length(keyword)); // das Keyword löschen aus dem String
      while (pos(#32, line) = 1) or (pos(#34, line) = 1) do delete(line, 1, 1);  // Leerzeichen und " löschen, die zwischen Keyword und dem gesuchten String sind
      result := copy(line, 1, pos(#34, line) -1); // gesuchter string
    end;
  end;
end;
Also der Code funzt zwar, aber ich finde, dass es nicht sehr elegant ist. Daher habe ich das gleiche nochmal mit Pointern gemacht:

Quellcode:function TParseFile.file_read(keyword : string) : string;
var line : string;
    p, q : PChar;
begin
  while not eof(data) do
  begin
    readln(data, line);  // lesen
    p := PChar(line);
    while (p^ <> #0) do  // solange durchlaufen, bis Ende der zeile
    begin
      if p^ in [#1..#32,#34] then Inc(p)  // wenn #1 - Leerzeichen oder " dann einen Buchstaben weitergehen ansonsten fängt ein Wort bzw ein String an
      else
      begin
        q := p;  // Zwischenspeichern von p
        while not (p^ in [#1..#31,#34]) do Inc(p);  // Ende des Wortes bzw Strings suchen
          form1.memo1.lines.add(copy(q, 1, p - q));  // Kopieren
      end;
    end;
  end;
end;
Das würde ich noch so weit verändern, dass der dann nur den gesuchten String ausgibt. Das ist alles kein Problem. Allerdings dachte ich daran, dass es auch mal passieren kann, dass sich jemand vertippt oder was in ne Datei schreibt, was da nicht reingehört und die Datei dann so aussehen würde:

Quellcode:"NUMMER1" blablabla "Nummer1, bla bla bla"
"NUMMER2" "Nummer2, bla bla bla"
Dann würden mir beide Funktion dann als String für NUMMER1 blablabla als Result geben. Daher dachte ich, dass man einfach immer nur die Wörter überhaupt beachtet, die in " " stehen, dann würde blablabla als Result ja wegfallen, allerdings habe ich irgendwie ne Denkblokade, wie man es anstellen könnte. Ich habe heute morgen von 6 Uhr bis 9 Uhr daran rumprobiert/überlegt etc und gerade auch nochmal, aber entweder hat das Prog dann nix gemacht bzw. ist abgeschmiert, es hat einfach nur die ganze Zeile ausgegeben oder jedes Wort (bei Funktion 2), auch das, was nicht ausgegeben werden sollte.
Daher wollte ich fragen, ob jemand ne gute Idee hat, wie man sowas lösen könnte.
Vielen Dank schonmal im Vorraus :)

btw, ich habe mal die Sources hochgeladen:
http://mitglied.lycos.de/feigling9/file-parser.htm

--

zum Seitenanfang zum Seitenende Profil || Suche
001
16.05.2003, 23:24
Fraghunter



ich kenn mich zwar nicht soo gut mit delphi aus *g*, aber hat das keine regExp?
*faulsei*

--

Nihil timeo, nulla re opprimor, nulli periculo cedo.
www.TheDoenerKing.de

zum Seitenanfang zum Seitenende Profil || Suche
002
17.05.2003, 00:07
feigling



Was ist ne regExp ? O_o
Meinst du nen register bereich, um das als Komponente zu reggen und zu adden bei Delphi ?
Wenn ja, wozu brauch ich das ?

--

zum Seitenanfang zum Seitenende Profil || Suche
003
17.05.2003, 00:47
Fraghunter



nene Regular Expression.
Noch nie gehört?

--

Nihil timeo, nulla re opprimor, nulli periculo cedo.
www.TheDoenerKing.de

zum Seitenanfang zum Seitenende Profil || Suche
004
17.05.2003, 00:52
feigling



Nö, was soll das sein ?

--

zum Seitenanfang zum Seitenende Profil || Suche
005
17.05.2003, 02:16
Fraghunter



oje *nachdenk*
Regular Expressions sind eine Möglichkeit, nach so ziemlich allem zu suchen.
Also Reguler Expressions sind sozusagen die erweterte Version der Wilcards ;)
Nur eben extrem erweiter, so dass du wirklich anch so ziemlich allem suchen kannst.
"Das Problem bei RegExp ist, dass man sie nicht beschreiben kann, man muss sie gesehen haben" ;)

Und vor allem kannst du damit eben so ziemlich alles parsen.
Wenn du deine ganze Datei in einen String lädst, müsstest du sie einfach nurnoch mit der Regular Expression
"(\S*?)"(.*?)"(.*?)"
"bearbeiten", und schon hättest du die gsammte Datei fein säuberlich geparst in Bezeichnung und Inhalt

Es gäbe aber noch zu erwähnen, dass es tausende Versionen von RegExp giebt, und alle haben einen leicht veränderten Syntax. Das beispiel ist im Pearl Syntax, der wohl auch am weitesten verbreitet sin sollte.

--

Nihil timeo, nulla re opprimor, nulli periculo cedo.
www.TheDoenerKing.de

zum Seitenanfang zum Seitenende Profil || Suche
006
17.05.2003, 02:52
feigling



Aha und was bringt mir das jetzt bei meinen Funktionen ? :]

--

zum Seitenanfang zum Seitenende Profil || Suche
007
17.05.2003, 04:27
theDon



besorg dir eine xml-lib für delphi, das erspart dir eine menge ärger.

--

\o tanz den naziprau! o/

And more than ever, I hope to never fall,
Where enough is not the same it was before

zum Seitenanfang zum Seitenende Profil || Suche
008
17.05.2003, 07:31
feigling



Hrm, will ich nicht O_o
Für das Projekt will ich keine vorgefertigten dlls etc nehmen.
Hat denn nicht einer ne Idee, wie man Funktion 1 oder 2 noch umschreiben kann ? Wenn nicht, dann nehm ich halt Funktion 1, fertig.

--

zum Seitenanfang zum Seitenende Profil || Suche
009
17.05.2003, 10:41
Fraghunter



was dir das bringen soll?
nunja, ich kann ein Delphi, aber das könnte dann so ausehen:
preg_match_all('"(\S*?)".*?"(.*?)"',file,match);
und schon hättest du alle DAteiinhalte in nem array - schön sauber aufgelöst.

Aber da du ja nichts fremdes verwenden willst, und Delphi sicher keine RegExp standartmäsig dabei hat, ist das hier wohl sowieos nichts für dich.

achso zu deiner verschreibfrage, mach doch einfach das hier (*delphiVersuch* :D)

while ((pos(#34, line) = 0) do delete(line, 1, 1);
delete(line, 1, 1); // Leerzeichen und " löschen, die zwischen Keyword und dem gesuchten String sind

--

Nihil timeo, nulla re opprimor, nulli periculo cedo.
www.TheDoenerKing.de


Dieser Beitrag wurde am 17.05.2003 um 10:45 von Fraghunter bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
010
17.05.2003, 15:20
theDon



Zitat:
Fraghunter postete
preg_match_all('"(\S*?)".*?"(.*?)"',file,match);
Quellcode:my @match = ($file_content =~ /"(\S*?)".*?"(.*?)")/g);wenn schon php, dann kannst du auch gleich U als modifier nehmen und dir die ? sparen.

--

\o tanz den naziprau! o/

And more than ever, I hope to never fall,
Where enough is not the same it was before

zum Seitenanfang zum Seitenende Profil || Suche
011
18.05.2003, 12:42
Archangel



Zitat:
Daher dachte ich, dass man einfach immer nur die Wörter überhaupt beachtet, die in " " stehen, dann würde blablabla als Result ja wegfallen, allerdings habe ich irgendwie ne Denkblokade, wie man es anstellen könnte
wie wärs damit:
du liest solange ein zeichen (c) ein, bis es ein '"' ist, speicherst das eingelesene aber nicht.. dann liest du bis zum nächsten '"' ein und speicherst das zwischen den beiden "" eingelesene in einem string.. und dann wiederholst du das von vorne, du liest also ein bis ein '"' auftaucht und dann speicherst du das eingelesene bis zum nächsten '"'

wenn ich das richtig verstehe (kann kein delphi), sollte das so aussehen
Quellcode:function TParseFile.file_read(keyword : string) : string;
var line : string;
    p, q : PChar;
begin
  while not eof(data) do
  begin
    readln(data, line);  // lesen
    p := PChar(line);
    while (p^ <> #0) do  // solange durchlaufen, bis Ende der zeile
    begin
        while(p^ <> #34 and p^ <> #0) do Inc(p);   // alles ignorieren, was kein " oder das ende der zeile ist
        if(p^ = #0) then
            break; // kA wie das in delphi heißt, schleife verlassen
        
        Inc(p);
        q := p;
        while(p^ <> #34 and p^ <> #0) do Inc(p);
        form1.memo1.lines.add(copy(q, 1, p-q));
        if(p^ <> #0) then
            Inc(p); // wenn p ein " ist, dann um eins erhöhen, ansonsten nicht, damit die schleife abbricht
    end;
  end;
end;
oder so.. kA.. o_O

--

Mar 01 01:10:13 <voice> jo
Mar 01 01:10:40 <voice> bis dann ^^
Mar 01 01:11:20 <Archangel> jo
**** ENDING LOGGING AT Tue Mar 1 01:58:13 2005


Dieser Beitrag wurde am 18.05.2003 um 12:47 von Archangel bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
012
19.05.2003, 02:30
feigling



Funzt perfekt :)
Big thx.
Sowas habe ich auch versucht, aber irgendwie hat es nicht das getan, was es sollte.

--

zum Seitenanfang zum Seitenende Profil || Suche