Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Im String Nach Wort suchen und nebenstehendes auslesen (https://www.delphipraxis.net/187545-im-string-nach-wort-suchen-und-nebenstehendes-auslesen.html)

CVi 8. Dez 2015 07:29

Im String Nach Wort suchen und nebenstehendes auslesen
 
im string nach wort suchen und nebenstehende (in hoch Komma) werte auslesen?

meinstring := 'Name1= "Meier" Vorname= "Bernd" Strasse= "Hauptstrasse 22" usw....'

die Reihenfolge des strings kann variieren oder auch andere Daten hinzukommen.

also zb.
meinstring := 'Name1= "Meier" Name2= "Schmidt" Strasse= "Hauptstrasse 22" Vorname= "Bernd" usw....'

nun möchte ich, egal wie der string aufgebaut ist in dem meinstring zb. nach Strasse
suchen und er soll mir Hauptstrasse 22 ausgeben.

mit functionen wie getstring und pos/posex komme ich da irgendwie nicht weiter.

entweder denke ich zu kompliziert oder es ist wirklich nicht so einfach :?
HILFE !!!

baumina 8. Dez 2015 07:47

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Hast du den String selbst so aufgebaut, oder ist der zwingend so vorgegeben? Wenn Du ihn selbst so aufgebaut hast, dann mach das besser über eine Liste. Ist der String so vorgegeben, müsstest du das mit pos schon hinbekommen, zeig mal deinen Code dazu.

CVi 8. Dez 2015 08:00

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Der ist leider zwingend so vorgegeben. (wird von einem fremdprogramm empfangen).
einen wirklich post-baren code habe ich im Moment nicht da ich nur am rumprobieren bin
und ständig wieder auf anfang stehe :(

mein Problem bei pos oder ähnlichem ist, das die werte in den hoch kommas bei jedem
datensatz unterschiedlich lang sind und ich so den einstiegs bzw. austiegspunkt nicht
ermitteln kann.

Sir Rufo 8. Dez 2015 08:07

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Um die Werte aus dem Daten-String zuverlässig herauslesen und schreiben zu können muss man den Daten-String parsen.

Beim Parsen wird dann auch die Struktur auf Gültigkeit untersucht.

Dieser Parser übersetzt dann den Daten-String in eine Struktur (hier eine Key-Value-Liste) mit der man dann im Programm weiter arbeiten kann. Praktischerweise baut man sich auch noch einen Writer, der diese Struktur dann wieder in so einen Daten-String schreiben kann.

Mit dem Daten-String selber sollte man nie arbeiten (es sei denn, man steht auf Schmerzen) :mrgreen:

Gollum 8. Dez 2015 08:20

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Hallo,

mal auf die Schnelle, mit Pos und PosEx:

Delphi-Quellcode:
function FindeWert(const aText, aSuche:String):String;
var x1, x2:Integer;
begin
  Result:='';
  x1:=Pos(aSuche, aText); // Ist Suchtext überhaupt vorhanden?
  if (x1>0) then
  begin
    x1:=PosEx('"', aText, x1+Length(aSuche)); // 1. Anführungszeichen suchen
    if (x1>0) then                           // gefunden?
    begin
      x2:=PosEx('"', aText, x1+1);           // 2. Anführungszeichen suchen
      if (x2>0) then                         // gefunden?
        Result:=Copy(aText, x1+1, x2-x1-1)   // Ergebnis zusammenbasteln
    end;
  end;
end; // FindeWert
Nun kannst Du den entsprechenden Wert folgendermaßen erhalten:
Delphi-Quellcode:
...
const
  teststring='Name1= "Meier" Name2= "Schmidt" Strasse= "Hauptstrasse 22" Vorname= "Bernd" usw....';
...
...
ShowMessage(FindeWert(teststtring, 'Strasse='));

baumina 8. Dez 2015 08:27

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Und wenn der Name2 "Strassemann" lautet hast ein Problem.

Sir Rufo 8. Dez 2015 08:29

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Dieser Ansatz hilft nur dann weiter, wenn man ausschliessen kann, dass so ein Keyword niemals in den Daten enthalten ist.

Genau das wird man aber nicht können ;)

Es führt kein Weg am Parsen vorbei, denn man muss die Struktur analysieren um Beschreibung und Daten zu erkennen.

UPDATE
Aus diesem Grund ist man auch gut beraten, wenn man sich zum Datenaustausch auf ein Standard-Format (JSON, XML, YAML, ...) einigt, denn dort ist die Wahrscheinlichkeit sehr hoch eine fertige Bibliothek nutzen zu können.

Klaus01 8. Dez 2015 08:39

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
.. noch ein Ansatz:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  meinstring: String;
  RegEx: TPerlRegEx;
begin
  meinString := 'Name1= "Meier" Vorname= "Bernd" Strasse= "Hauptstrasse 22"';
  RegEx := TPerlRegEx.Create;
  try
    RegEx.RegEx := 'Strasse= "(.+)"';
    RegEx.Subject := meinString;
    if RegEx.Match then
      showMessage(RegEx.MatchedText+' '+RegEx.Groups[1])
    else
      showMessage('nothing found')
  finally
    RegEx.free;
  end;
end;
Grüße
Klaus

Sir Rufo 8. Dez 2015 08:45

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Such mal im Netz, warum man eine HTML/XML Datei nicht mit RegEx untersuchen soll.

Aus dem gleichen Grund sollte man auch hier darauf verzichten.

Und hier das Beispiel, wo du mit deinem Ansatz auf die Nase fällst:
Code:
Name1= "Meier" Whatever= "Strasse= ""Nö""" Vorname= "Bernd" Strasse= "Hauptstrasse 22"
Zudem sollte man immer berücksichtigen, dass es durchaus üblich ist den Whitespace zu ignorieren. Dadurch ist dann
Code:
Vorname= "Bernd" Strasse= "Hauptstrasse 22"
gleich
Code:
Vorname="Bernd" Strasse="Hauptstrasse 22"
gleich
Code:
Vorname=     "Bernd" Strasse=     "Hauptstrasse 22"
gleich
Code:
Vorname = "Bernd" Strasse = "Hauptstrasse 22"
gleich
Code:
Vorname= "Bernd"
Strasse= "Hauptstrasse 22"
usw. usw.

Nur deswegen ist es z.B. bei JSON möglich, den JSON-String auch formatiert auszugeben.

Jumpy 8. Dez 2015 08:53

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Ein anderer Schnellschuss-Versuch, wobei ein Parser sicher die bessere Lösung ist, aber die Fragestellung des TE weist darauf hin, dass das noch zu schwierig sein könnte. Das Folgende funktioniert aber nur, wenn die Struktur des Strings immer genauso ist, wie in den Beispielen. Eine Prüfung dessen, wie mit einem Parser hat man nicht:

Delphi-Quellcode:
function GetValue(InputString, ValueName:String):String;
var s:TStringlist;
    meinString:String;
begin
  s:TStringlist.create;
  meinString := InputString;
  //Bereinigen:
  meinString := StringReplace(meinString,'= "','=',[rfReplaceAll]);
  meinString := StringReplace(meinString,'="','=',[rfReplaceAll]);
  meinString := StringReplace(meinString,'" ',',',[rfReplaceAll]);
  s.DelimitedText:=meinString;
  Result:=s.Values[ValueName];
  s.free;
end;

CVi 8. Dez 2015 08:55

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Danke Klaus

genau das habe ich gesucht/versucht :-D

baumina 8. Dez 2015 09:10

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Aber

Delphi-Quellcode:
Showmessage(GetValue('Name1= "Meier" Name2= "Schmidt" Strasse= "Hauptstrasse 22" Vorname= "Bernd"', 'Vorname'));

Liefert :
Zitat:

Bernd"

Sir Rufo 8. Dez 2015 09:12

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Zitat:

Zitat von CVi (Beitrag 1323721)
Danke Klaus

genau das habe ich gesucht/versucht :-D

Schreib dir wenigstens in den Quellcode hinein:
Delphi-Quellcode:
// Wenn es mal seltsame Ergebnisse gibt,
// dann muss ich wohl doch mit einem Parser ran
;)

Sir Rufo 8. Dez 2015 09:14

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Zitat:

Zitat von baumina (Beitrag 1323722)
Aber

Delphi-Quellcode:
Showmessage(GetValue('Name1= "Meier" Name2= "Schmidt" Strasse= "Hauptstrasse 22" Vorname= "Bernd"', 'Vorname'));

Liefert :
Zitat:

Bernd"

Darum sind Unit-Tests auch zwingend notwendig.

vagtler 8. Dez 2015 09:29

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1323724)
[...] Darum sind Unit-Tests auch zwingend notwendig.

Ach, komm, (Unit-)Testing wird überbewertet. Reicht doch, wenn es kompiliert... :mrgreen:

Jumpy 8. Dez 2015 09:31

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1323724)
Zitat:

Zitat von baumina (Beitrag 1323722)
Aber

Delphi-Quellcode:
Showmessage(GetValue('Name1= "Meier" Name2= "Schmidt" Strasse= "Hauptstrasse 22" Vorname= "Bernd"', 'Vorname'));

Liefert :
Zitat:

Bernd"

Darum sind Unit-Tests auch zwingend notwendig.

Leider hab ich es noch nicht geschafft DUnit im Browser einzubinden und für die fehlerfreie Einbindung im Kopf fehlte noch der Kaffee. :-D
Ich bin da auch nicht ganz sicher, was die optimale Variante ist, um das zu berichtigen, vielleicht:
Delphi-Quellcode:
  if meinString[Length(meinString)]='"' then
    meinString=Copy(meinString,1,Length(meinString)-1);
Für alle weiteren Probleme die mit der Struktur noch auftreten könnten ist dieser Schnellschuss aber dann auch wirklich am Ende und es hilft nur noch ein Parser.

Jasocul 8. Dez 2015 12:06

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Mal eben schnell hingetippt.
Die Idee dahinter: Mit einer StringList kann man auch Wertepaare "verwalten".
Da der String ja immer gleich aufgebaut sein soll, werden erstmal überflüssige Leerzeichen rausgeschmissen. Die Paare sind durch ein "=" verbunden. Ich meine, dass dann kein Leerzeichen dazwischen sein darf. Die Anführungszeichen mit folgendem Leerzeichen trennt ein Wertepaar vom nächsten. Der Sonderfall des letzten Wertepaares muss natürlich berücksichtigt werden.

Delphi-Quellcode:
var
  SL : TStringList;
  Teil, Mein : String;
begin
  SL := TStringList.Create;
  SL.NameValueSeparator := '=';
  Mein := StringReplace('Name1= "Meier" Name2= "Schmidt" Strasse= "Hauptstrasse 22" Vorname= "Bernd"', '= "', '="', [rfReplaceAll]);
  if length(Mein) > 0 then
  begin
    Repeat
      Teil := copy(Mein, 1, Pos('" ', Mein));
      if Teil = '' then
      begin
        Teil := Mein;
      end;
      SL.Add(Teil);
      Delete(Mein, 1, Pos('" ', Mein) + 1);
    until Pos('" ', Mein) = 0;
  end;
  ShowMessage(SL.Values['Strasse']);
end;
Dann kann man einfach über:
Delphi-Quellcode:
StringList.Values['Strasse']
zum Beispiel an den Straßennamen kommen.

Oder denke ich jetzt zu einfach?

Amateurprofi 8. Dez 2015 12:29

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Nicht sehr elegant, und nur oberflächlich geprüft:

Delphi-Quellcode:
FUNCTION GetValue(const Text,Id:String):String;
var I,J,K,Len:Integer;
begin
   Result:='';
   if (Text='') or (Id='') then Exit;
   Len:=Length(ID);
   J:=0;
   repeat
      K:=PosEx('"',Text,J+1); // erstes '"'
      J:=PosEx('"',Text,K+1); // zweites '"'
      if J=0 then Exit;
      I:=J;
      while (I>0) and (Text[I]<>'=') do Dec(I);
      Dec(I);
      while (I>0) and (Text[I]=' ') do Dec(I);
      Dec(I,Len);
      if I>=0 then
         if SameText(Copy(Text,I+1,Len),Id) then begin
            if I<>0 then begin
               while (I>1) and (Text[I]=' ') do Dec(I);
               if (I>1) and (Text[I]<>'"') then Exit;
            end;
            Result:=Copy(Text,K+1,J-K-1);
            Exit;
         end;
   until False;
end;

Sir Rufo 8. Dez 2015 13:05

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Das Grundproblem ist und bleibt, dass die einzelnen Zeichen in dem Daten-String eine unterschiedliche Bedeutung haben können abhängig von den Zeichen davor.

Darum kann man nicht anhand eines einzelnen Zeichens die Bedeutung erkennen.
Darum muss man parsen um diese Bedeutung interpretieren zu können.
Darum braucht man auch eine komplette Beschreibung des Datenformats.
Darum braucht man auch komplexe Beispiele.
Code:
Key=Name1
Value=Ein = "schöner" = Tag

Name1= "Ein = ""schöner"" = Tag"
Darum braucht man auch Unit-Tests um diese komplexen Beispiele gegen die Implementierung zu testen.

Jasocul 8. Dez 2015 13:20

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Völlig richtig, aber das Beispiel ist schon sehr konstruiert.
Es muss klar definiert sein, was vom Fremdprogramm kommt. Ansonsten wird auch der beste Parser nicht alle Fälle abdecken können. Auch ein Parser kann nur nach definierten Regeln die Daten analysieren.

Aber wie du schon weiter oben geschrieben hast, sollte besser ein Standard-Format verwendet werden, falls möglich.

Sir Rufo 8. Dez 2015 14:44

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Aber nur mit diesen konstruierten Beispielen kann man die Grenzen der Struktur oder der Implementierung testen bzw. die Schwachstellen aufzeigen.

Zu 95% wird mit Ideal-Beispielen getestet und da funktioniert immer alles ganz toll.

Sobald der Faktor Mensch (Eingabe von Daten) ins Spiel kommt ticken die Uhren aber anders :stupid:

Perlsau 8. Dez 2015 14:53

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Da muß ich Ritter Rufo beipflichten. So lange nicht gesichert ist, wie der zu analysierende String zusammengesetzt ist, wird es immer potentielle Fehlerquellen im Parser geben, denn schließlich kann jeder Wert auch den Text enthalten, der "zufällig" einen Key darstellt. Wissen wir, ob die Werte (das, was nach dem = kommt) auch immer in Anführungszeichen stehen? Wissen wir, ob das = immer vorhanden ist? Was am Format dieses Strings ist denn überhaupt als zuverlässig zu bezeichnen? Das kann nur der TE beantworten.

baumina 8. Dez 2015 15:15

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Unbedingt sollte man auch klären wie der String aussieht, wenn der Benutzer ein Anführungszeichen (") im Text eingegeben hat. Ich hatte da mal lustige Ergebnisse mit Zoll-Angaben in der Artikelbezeichnung (z.B. 24" Bildschirm).

p80286 8. Dez 2015 15:20

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Hallo ist da noch jemand oder seid Ihr alle entschwebt?
Auch wenn Ihr (insbesoders Sir Rufo) recht habt, ich glaube der TE kann mit einem Parser und erst recht mit der Formulierung der notwendigen Regeln nicht so viel anfangen.

@CVi
Dir möchte ich #17 ans Herz legen, der Vorschlag scheint mir am wenigsten Probleme zu bereiten. Trotzdem solltest Du das hier geschriebene nicht ignorieren, das könnte sich später rächen.

Gruß
K-H

Sir Rufo 8. Dez 2015 16:35

AW: Im String Nach Wort suchen und nebenstehendes auslesen
 
Wir sind nicht "entschwebt" sondern kommen nur unserer Sorgfaltspflicht nach.

Wenn ich die Grenzen meiner Implementierung kenne, dann stehe ich bei einem Problem "Oh, was kommt denn da rein und warum tut das nicht?" nicht wie der Ochs vorm Berge, sondern ich weiß wo ich ansetzen muss und verplempere nicht unnötig Zeit mit Haare raufen (denn die Implementierung ist doch toll - oder doch nicht?).

Dabei ist es unerheblich, ob ich die neue Implementierung umsetzen kann oder nicht. Das kann man lösen (Lernen oder outsourcen).


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr.

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