![]() |
Einen Komma-Text richtig trennen.
Hallo liebe Delphi-Praxis Mitglieder
Ich habe ein kleines Problem, wo ich mal wieder eure Hilfe brauche. Ich will einen String in ein bestimmtes Format bekommen. Der String könnte z.B. so in die Funktion reinkommen. Zitat:
Ist das mit einfachen Mitteln möglich? Mir fehlt dafür leider ordentlich Basiswissen von Delphi. Ach ja, wichtige Information, ich arbeite hier mit Delphi 7 Professional. Schon mal vielen Dank im voraus und nun folgt der bisherige Code, der zwar ansich gut funktioniert aber mit Kommas und Leerzeichen im Namen nicht zurecht kommt. Gruß Michael
Delphi-Quellcode:
function getSender(List: Boolean; Value: String): String;
(* Wandelt einen String mit SenderId in eine Senderliste oder einen kommagetrennen SenderSting ohne SenderId *)
Delphi-Quellcode:
function getSender(List: Boolean; Value: String): String;
var Sl : TStringlist; S : String; i : Integer; begin Sl := TStringlist.Create; sl.Text := Value; Result := ''; if sl.Count > 0 then begin S := Sl[0]; // Falls Text mehrzeilig sl.CommaText := S; for i := sl.Count -1 downto 0 do if pos('{', Sl[i]) > 0 then begin Sl[i] := CopyBis('{', SL[i]); end else sl.Delete(i); if List then Result := Sl.Text else begin Result := sl[0]; for i := 1 to sl.Count -1 do Result := Result + ', ' + Sl[i]; end; end; end; |
Re: Einen Komma-Text richtig trennen.
Was ist, wenn du nach "," einfach nach "}," suchst? Würde das dein Problem lösen?
|
Re: Einen Komma-Text richtig trennen.
Also mit einer TStringList klappt das schon mal nicht, die trennt nach jedem Komma.
Da muss man den String von Hand zerlegen. Beim ersten Wort mit Pos nach einem '{' suchen, mit Copy bis zu dieser Position dieses Wort auslesen. Dann mit Pos nach einem ',' suchen, und mit Delete den String bis zu dieser Position links abschneiden. Mit Trim evtl. führende Leerzeichen löschen, und dann weiter wie beim ersten Wort. |
Re: Einen Komma-Text richtig trennen.
Wie wär es denn mit Regexen?
Code:
([^{]+)(?={\d+},)
|
Re: Einen Komma-Text richtig trennen.
Vielleicht so...
Delphi-Quellcode:
function MyFunc(input:string):string;
var RegExpr:TRegExpr; begin RegExpr:=TRegExpr.Create; try RegExpr.ModifierG:=false; RegExpr.Expression:='{[0-9]*}'; Result:=RegExpr.Replace(input, '', true); finally RegExpr.Free; end; end; ![]() Gruss Thorsten |
Re: Einen Komma-Text richtig trennen.
Zitat:
![]() mfg Christian |
Re: Einen Komma-Text richtig trennen.
Regular Expressions sind natürlich viel eleganter! :-D
Gleich mal gucken gehen, ich bin begeistert! Ich bin leider teilweise geistig noch auf dem Stand von Delphi3, berufsbedingt... |
Re: Einen Komma-Text richtig trennen.
Das mit der Regular Expression-Geschichte wirkt interessant. Ich probier das mal aus. Bis hierher erstmal vielen Dank für die Hilfe. Ich schreib mal, wie weit ich damit gekommen bin.
Gruß Michael |
Re: Einen Komma-Text richtig trennen.
Zitat:
Z.B. bei Webanwendungen, die mit einer hohen Besucheranzahl fertig werden müssen, sollte man "normale" Stringverarbeitungsfunktionen immer regulären Ausdrücken vorziehen! Reguläre Ausdrücke werden nur bei komplexen Aufgaben benötigt, bei denen sich der Programmieraufwand nicht lohnt bzw. zu groß wird. LG, Xong PS: Natürlich ist das Problem bei reinen Single-User-Anwendungen nicht gegeben. |
Re: Einen Komma-Text richtig trennen.
in der Codelib gibt es einige Funktionen welche dir den String auch an "}," trennen können.
|
Re: Einen Komma-Text richtig trennen.
Hi,
folgende Funktion dürfte erledigen was du brauchst:
Delphi-Quellcode:
function TrenneText(sText, sDelim1, sDelim2, sDelimNew: String): String; var iPos1, iPos2: Integer; begin Result := ''; iPos1 := pos(sDelim1, sText); iPos2 := pos(sDelim2, sText); while ((iPos1 > 0) and (iPos2 > 0)) do begin Result := Result + copy(sText, 1, iPos1-1) + sDelimNew; sText := copy(sText, iPos2 + Length(sDelim2), Length(sText)); iPos1 := pos(sDelim1, sText); iPos2 := pos(sDelim2, sText); end; end; // aufruf in deinem Fall mit TrenneText('BORKUM{61}, BLA2{60}, REL{62}, EN/NORD{72}, ESSEN{59}, TRIN,KEN{70}, HERNE{71}, HSK1{67}, MAMA123{65}, KW/DINSL{64}, OBERHAUSEN{66}, EN/SÜD{73}, KW/MOERS{63}, HSK2{68}, HSK3{69}' , '{', '},', ','); |
Re: Einen Komma-Text richtig trennen.
autsch, bitte nicht die funktion verwenden. Dein Programm wird es dir auf längere sicht danken.
Durch
Delphi-Quellcode:
wird die Länge von Stringx immer wieder verändert, somit immer wieder neuer speicher angefordert und der alte umkopiert und bei einigen Speichermangern ist der Speicher danach derart fragmentiert das du probleme bekommen kannst wenn du wieder speicher anforderst.
Stringx := Stringx + irgendwas
schau dir mal das hier an: ![]() |
Re: Einen Komma-Text richtig trennen.
Ich hab grad das Problem grad mit dieser Regular Expression hinbekommen und war schon sehr angetan. Das werde ich mir mal genauer angucken, ob man die in Zukunft nicht häufiger mal gebrauchen kann. Trotzdem mal aber besten Dank bezüglich der Performance. Im Moment ist dies allerdings kein Problem, aber falls das in Zukunft mal der Fall sein wird, werd ich das im Hinterkopf behalten.
Ach ja. Ihr seid spitze. |
Re: Einen Komma-Text richtig trennen.
Zitat:
Jeder gute Compiler (mit dem ich mich auskenne) versucht einen String zu vergrößern, indem er er den Speicherplatz einfach vergrößert/verlängert. Erst wenn dies nicht klappt, wird ein vollkommen neuer Speicherplatz vergeben und der alte aufgelöst. Das hat C schon so gemacht und es würde mich wundern, wenn es in Delphi anders wäre. |
Re: Einen Komma-Text richtig trennen.
ich bin mir da ganz sicher. Mach einfach mal paar Performancetests und du wirst das erschreckende Ergebnis sehen.
Bei früheren Programmen konnte ich das ständige Vergrößern von Strings als Performancekiller Nummer eins ausmachen und wenne in Programm das ständig macht und einige Stunden durchläuft bekommt man schnell mal ein "out of memory". Das man angeforderten Speicher einfach vergrößern kann war mir neu. Aber wie dem auch ist, meine Tests haben bisher ergeben das ein ständiges vergrößern von Arrays, Strings etc. zu stargen Performanceeinbrüchen führt. Bist du dir sicher das C das schon gemacht hat? In C sind mir strings bisher noch gar nicht begegnet (was aber vielleicht auch an der minimalen Bibliothek bei der Microcontrollerprogrammierung liegt) |
Re: Einen Komma-Text richtig trennen.
In C gibt es ja auch keine Stringverarbeitung. =)
Dafür gibt es die Standardbibliotheken, in denen Stringfunktionen bereitgestellt werden. So erreicht man die Plattformunabhängigkeit von C (d.h. die Stringfunktionen sind betriebssystemspezifisch deklariert). Es gibt in C eine Funktion, deren Name mir gerade nicht einfällt. Mit der ist genau das möglich, was ich beschrieben habe. Es kann natürlich sein, dass der Delphi-Compiler das anders handhabt. Keine Ahnung. :stupid: Ich dachte ja nur... Alles andere wäre so ineffizient. Aber Ineffizienz ist schließlich auch der Preis für Bequemlichkeit, nicht wahr?! LG, Xong |
Re: Einen Komma-Text richtig trennen.
Hallo,
in Delphi sorgt die Prozedur ReallocMem() für die Vergrößerung eines bereits angeforderten Speicherblocks. Ist der Speicher hinter dem aktuellen Block in Benutzung, dann wird der aktuelle Block freigegeben und der größere Speicher an anderer Stelle zugeordnet. Der Reiz einer Regular Expression liegt für mich im nicht prozeduralen Ansatz, aber sie kann nie schneller sein, als eine gute handkodierte Lösung:
Delphi-Quellcode:
Freundliche Grüße
function PurgeId(const list: string): string;
var iPos, iDest: Integer; skipping: Boolean; begin skipping := False; SetLength(Result, Length(list)); iDest := 1; for iPos := 1 to Length(list) do if skipping then skipping := list[iPos] <> '}' else if list[iPos] = '{' then skipping := True else begin Result[iDest] := list[iPos]; Inc(iDest); end; SetLength(Result, Pred(iDest)); end; |
Re: Einen Komma-Text richtig trennen.
Zitat:
Delphi-Quellcode:
Sir Thornberry's Anmerkungen zur Performancebremse 'sString := sString + sSubString' kann ich nur beipflichten. Der Unterschied ist in etwa vergleichbar miz dem Unterschied in der Zubereitungszeit einer Tasse Nescafe und dem eigenhändigen Anbau, Ernte, Röstung, Malen und Brühen von jamiakanischem Blue Mountain. Wobei der Vergleich hinkt: Jamaican Blue Mountain ist es Wert, etwas länger zu warten, Stringkonkatenation hingegen nicht.
Function AlzPurgeID(Const list: String): String;
Var iStop, iPos, iDest: Integer; Begin iStop := Length(list); SetLength(Result, iStop); iDest := 0; iPos := 1; While iPos <= iStop Do Begin If list[iPos] = '{' Then While (iPos <= iStop) And (list[iPos] <> '}') Do inc(iPos) Else Begin Inc(iDest); Result[iDest] := list[iPos]; End; inc(iPos); End; SetLength(Result, iDest); End; Und nun: Assemblerfraktion und Performancegeeks vortreten, bitte! |
Re: Einen Komma-Text richtig trennen.
Zitat:
tja, und C hat keine strings... sind halt nur arrays of char... (nachbau in delphi PCHAR :-) ) |
Re: Einen Komma-Text richtig trennen.
Zitat:
Vielen Dank :dp: Gruß |
Re: Einen Komma-Text richtig trennen.
Ein wenig TERWI-Senf dazu...
Diese Funktion nutze ich schon seit ner kleinen Ewigkeit, um Strings - z.B. durch Komma oder andere Zeichen getrennt - zu zerlegen. Kann man dann logo auch rekursiv auf die Ergebnisse anwenden ...
Delphi-Quellcode:
Da würde ich gunfran's Beispiel erst mal grob nach Kommata zerlegen
function SplitStr(T : char; var S : string) : string;
var p : integer; begin Result := S; // Result ist zunächst S unverändert ! if s = '' then exit; // ... da gibts nix zu trennen p := Pos(T, S); // Position des Trennzeichens 'T' ermitteln if p > 1 then // Trennzeichen ist vorhanden ! begin // > JA Result := trim(Copy(S,1,p-1)); // Bis zum Trennzeichen aus S nach Result kopieren (links) S := trim(Copy(S,p+1,Length(S))); // Rest nach Trennz. in S zurückgeben (rechts) end else S := ''; // Kein Trenner - Result (links) ist S und S (rechts) ist leer end; Und dann weiter den Wert in {} ermitteln... Nur ne grobe Idee, nicht getestet !
Delphi-Quellcode:
Idee ohne Gewehr zum selber selbsterschiessen / weiterdenken... :spin:
...
s_org := 'BORKUM{61}, BLA2{60}, REL{62}, EN/NORD{72}, ESSEN{59}, TRINKEN{70}, HERNE{71}, HSK1{67}, MAMA123{65}, KW/DINSL{64}, OBERHAUSEN{66}, EN/SÜD{73}, KW/MOERS{63}, HSK2{68}, HSK3{69}'; repeat s_result := SplitStr(',', s_org); s_rest := s_result; // Edit: ... sonst wird das nix mit repeat until. // s_result prüfen... entweder leer oder was gültiges vor dem ',' // ggf. noch mal ein SplitStr('/', s_result) darauf um für ein '/' zu trennen.... Achtung: s_result wird verändert ! s_temp := SplitStr('{',s_result); // die {-Klammer vorne weg und den Rest erhalten // mach was mit s_temp vor dem { SetLength(s_result, Length(s_result - 1)); // die }Klammer hinten weg --- EDIT: Korrgiert... // mach hier was mit s_result until s_rest = ''; // Edit: oder until (Pos(',', s_org) < 1); PS: Ich bin da nicht so der Performance-Kasper. Sollte logo schon zügig gehen... Aber mit der SplitStr-Func habe ich schon relativ dicke Daten im xx-MB-Format durchwurstet und ich würde mach dumpf behaupten, das da die Platte (von der gelesen wurde) eher das langsamste Teil in der Kette war... |
DP-Maintenance
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage |
Re: Einen Komma-Text richtig trennen.
und hast dir
![]() |
Re: Einen Komma-Text richtig trennen.
Zitat:
|
Re: Einen Komma-Text richtig trennen.
Das Wort "feste Feldlänge" ist noch nicht gefallen. Damit sind Trennzeichen-Probleme ein für allemal aus der Welt geschafft. Selbst dann wenn ein DAU "Herr M;ller" als Name gespeichert hat. Das Komma selber ist wegen Dezimalzahlen sowieso auszuschließen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:16 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 by Thomas Breitkreuz