![]() |
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 !!! |
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.
|
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. |
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: |
AW: Im String Nach Wort suchen und nebenstehendes auslesen
Hallo,
mal auf die Schnelle, mit Pos und PosEx:
Delphi-Quellcode:
Nun kannst Du den entsprechenden Wert folgendermaßen erhalten:
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
Delphi-Quellcode:
...
const teststring='Name1= "Meier" Name2= "Schmidt" Strasse= "Hauptstrasse 22" Vorname= "Bernd" usw....'; ... ... ShowMessage(FindeWert(teststtring, 'Strasse=')); |
AW: Im String Nach Wort suchen und nebenstehendes auslesen
Und wenn der Name2 "Strassemann" lautet hast ein Problem.
|
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. |
AW: Im String Nach Wort suchen und nebenstehendes auslesen
.. noch ein Ansatz:
Delphi-Quellcode:
Grüße
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; Klaus |
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:
Zudem sollte man immer berücksichtigen, dass es durchaus üblich ist den Whitespace zu ignorieren. Dadurch ist dann
Name1= "Meier" Whatever= "Strasse= ""Nö""" Vorname= "Bernd" Strasse= "Hauptstrasse 22"
Code:
gleich
Vorname= "Bernd" Strasse= "Hauptstrasse 22"
Code:
gleich
Vorname="Bernd" Strasse="Hauptstrasse 22"
Code:
gleich
Vorname= "Bernd" Strasse= "Hauptstrasse 22"
Code:
gleich
Vorname = "Bernd" Strasse = "Hauptstrasse 22"
Code:
usw. usw.
Vorname= "Bernd"
Strasse= "Hauptstrasse 22" Nur deswegen ist es z.B. bei JSON möglich, den JSON-String auch formatiert auszugeben. |
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; |
AW: Im String Nach Wort suchen und nebenstehendes auslesen
Danke Klaus
genau das habe ich gesucht/versucht :-D |
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:
|
AW: Im String Nach Wort suchen und nebenstehendes auslesen
Zitat:
Delphi-Quellcode:
;)
// Wenn es mal seltsame Ergebnisse gibt,
// dann muss ich wohl doch mit einem Parser ran |
AW: Im String Nach Wort suchen und nebenstehendes auslesen
Zitat:
|
AW: Im String Nach Wort suchen und nebenstehendes auslesen
Zitat:
|
AW: Im String Nach Wort suchen und nebenstehendes auslesen
Zitat:
Ich bin da auch nicht ganz sicher, was die optimale Variante ist, um das zu berichtigen, vielleicht:
Delphi-Quellcode:
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.
if meinString[Length(meinString)]='"' then
meinString=Copy(meinString,1,Length(meinString)-1); |
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:
Dann kann man einfach über:
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;
Delphi-Quellcode:
zum Beispiel an den Straßennamen kommen.
StringList.Values['Strasse']
Oder denke ich jetzt zu einfach? |
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; |
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:
Darum braucht man auch Unit-Tests um diese komplexen Beispiele gegen die Implementierung zu testen.
Key=Name1
Value=Ein = "schöner" = Tag Name1= "Ein = ""schöner"" = Tag" |
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. |
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: |
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.
|
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).
|
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 |
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