AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Zeichen in String ersetzen

Ein Thema von JanWe · begonnen am 20. Dez 2016 · letzter Beitrag vom 20. Dez 2016
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von JanWe
JanWe

Registriert seit: 23. Mär 2015
Ort: NRW
78 Beiträge
 
Delphi 7 Personal
 
#1

Zeichen in String ersetzen

  Alt 20. Dez 2016, 00:02
Betrifft:
DELPHI 5

Hi,

VORGESCHICHTE:
eine Freundin von mir hat für eine Studie Versuche mit diversen Programmen und Verfahren durchgeführt und diese Ergebnisse mit Programmen wie u.a. SPSS, Excel, usw. bearbeitet.
Doch leider ist es zum Gau gekommen, da sie mehrere OriginalDateien überschrieben hat. (dauert jetzt zu lange das detailliert zu erklären).
Die Daten sind zwar glücklicherweise noch einmal vorhanden, allerdings quer in 1 Datei verwurstet.

PROBLEM:
Jetzt hab ich ihr versprochen, ich würde ihr dabei helfen.
Und hab versucht ein Programm zu entwickeln, das nach Zeichen sucht und diese Daten extrahieren oder zumindest erstmal trennen kann.

Dabei soll bei Auftreten von 3 Zeichenkombinationen wie folgend verfahren werden: (für mich sind es nachher noch mehr, aber wenigstens die schon mal ..)
  1. X01 soll durch den String ' Typ A: ' (steht für Fragetyp A) ersetzt werden
  2. 01 steht für ' Typ B: ' (für Fragetyp B)
  3. die Datenseparator (Komma ',') sollen, falls sie mehrfach vorkommen durch ein einzelnes Vorkommen ersetzt werden

Delphi-Quellcode:
procedure TForm1.Button8Click(Sender: TObject);
var Rest, s, TEX: string;
  Menge, Laenge, i: Integer;
begin
// Beispielkette
  S := '2,9,0171,,25,01640X0174,01747,23,,,,47X014747'; //

  S := '0,,25,01640X0174,01747,23,,,,47X014747'; // vorne gekürzte Kette bringt wieder andere Ergebnisse
  laenge := length(s);
  i := 0;
  Menge := 0;
  while i < laenge do
  begin
    inc(i);
      if (s[i] = 'X') and (s[i + 1] = '0') then // -> x0
    begin
      if (s[i + 2] = '1') then // -> wenn X01
        if Menge > 0 then
        begin
          TEX := TEX + ',' + ' Typ: A ';
          Menge := 0;
        end
        else
          TEX := TEX + ' Typ: A ';
      inc(i);
    end
    else ////////////////////////////////////
      if (s[i] = '0') and (s[i + 1] = '1') then // -> normaler 01
      begin
        if Menge > 0 then
        begin
          TEX := TEX + ' Typ: B '; // Antworttyp
          Menge := 0;
        end
        else TEX := TEX + ',' + ' Typ: B '; // Antworttyp B
        inc(i);
      end
      else ////////////////////////////////////
        if (s[i] = ',') then // DOPPELTE Trenner finden
        begin
          inc(Menge);
        end
        else ////////////////////////////////////

          if Menge > 0 then
          begin
            Caption := s[i];
            if Menge = 1 then
              TEX := TEX + ',' + s[i]
            else
              TEX := TEX + s[i];
           Menge := 0;
          end
          else
        // alles andere
       
            TEX := TEX + s[i]; // alle anderen Zeichen

  end; // END WHILE
  Memo2.text := TEX;
  Memo1.text := S;

end; // Ende Buttonfunktion
Ich hab jetzt seit Freitag immer wieder rumprobiert und mit mehreren Zeichenketten [s.o.] versucht.
Jedes Mal kamen andere, neue Verluste von Zeichen heraus.

Aus der folgenden Zeichenkette z.B.
0,,25,01640X0174,01747,23,,,,47X014747

025 Typ: B 640 Typ: A174 Typ: B 747,2347 Typ: A 14747
kommt ^^ => d.h.
(1. Doppelkomma => verschwindet ganz,
Komma nach der 25 ist auch weg
aus X01 wird aber die 1 dennoch übernommen
Komma verschwindet, usw.) - aber das ist ja nicht richtig!

Ich hab zwar jetzt an so vielen Stellen herumgeschraubt und verbessert,
aber es will nicht komplett gelingen.

Sieht vielleicht einer von Euch, woran es liegt?
oder gibt es am Ende eine komplett einfachere Lösung? (ich habe keine Informatikerausbildung und Algorithmenentwicklung nicht nativ gelernt)

Vielen Dank.
Jan
Allen demnächst ein gutes 2023!

Geändert von JanWe (20. Dez 2016 um 00:45 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 00:23
Warum machst du es dir so schwer und versuchst alles gleichzeitig und auch "Mehrfachzeichen" mit Einzelzeichenoperationen zu verarbeiten?

Wenn/da es nicht auf's Tempo ankommt.

Delphi-Quellcode:
while ContainStr(S, ',,') do // nach zwei Durchläufen sind auch ',,,' nur noch ',' usw.
  S := ReplaceStr(S, ',,', ',');
Und dannach
Delphi-Quellcode:
S := ReplaceStr(S, 'X01', '' Typ A: ');
S := ReplaceStr(S,
'01', '' Typ B: ');
Man kann natürlich auch mit Pos/PosEx Zeichenketten suchen und über Delete+Insert ersetzen.
Oder per RegEx nach "mehreren" Kommas suchen und sie durch ein ',' ersetzen.

Mit 2 TStringList kann man auch Einzelzeilen und darin einzelne Teilstrings verarbeiten.
Erste StringList für die Zeilen und dann jeweils eine Zeile in TStringList.CommaText oder TStringList.DelimitedText kopieren.
In der 2. StringList alle Werte ohne inhalt löschen und in den einzelwerten das ReplaceStr anwenden.
Nach auslesen und zurückschreiben des CommaText sind dann auch mehrfache Kommas aufgelöst (",," ist ein Leerstring zwischen den Kommas )
und auch Kommas am Anfang und Ende sind weg (falls man beim Delete nicht den ersten und letzten Leerstring beibehält).
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von JanWe
JanWe

Registriert seit: 23. Mär 2015
Ort: NRW
78 Beiträge
 
Delphi 7 Personal
 
#3

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 01:02
Hi,

danke Dir für Deine Antwort:
Allerdings muß ich dazu sagen, dass ich nur Delph 5 habe (und derzeit keinen Platz, um Lazarus oder eine Trial zu installieren, da ich gerade wichtige Planungsvideos auf meinem Laptop habe.

Mhh, ja, sicher ist da viel auf einemal.
Angefangen hatte ich auch erst nur mit den x01 und 01 (Typ A; Typ B) Zeichenketten und die bearbeitet. Das ging auch gut.

Dann dachte ich mir .. Ok, die restlichen kannste ja noch mit Kommt ein Komma vor oder wenn, sogar mehrere ...


und eigentlich würde ich das gerne mit Pointern machen (darum auch der Inc()-operator und einzelne Vegleich

hier nochmal der VErsuch einer verkürzten Version der oben ... aber ich seh gerade, der Übersicht hilft das gar nicht.
und die Ergebnisse sind auch wieder total andere:

0,,25,01640X0174,01747,23,,,,47X014747
wird zu
025, Typ B: ,640, Typ A: 174, Typ B: ,747,2347, Typ A: 14747
Delphi-Quellcode:
procedure TForm1.Button9Click(Sender: TObject);
var Rest, s, TEX: string;
  Menge, Laenge, i: Integer;
begin
// 8 8 88 888 X01
  S := '2,9,0171,,25,01640X0174,01747,23,,,,47X014747'; //

  S := '0,,25,01640X0174,01747,23,,,,47X014747'; //
  laenge := length(s);
  i := 0;
  Menge := 0;
  while i < laenge do
  begin
    inc(i);
    if s[i] = '5then
      Caption := s[i];
    if (s[i] = 'X') and (s[i + 1] = '0') then // -> x01
    begin
      if (s[i + 2] = '1') then // wenn X01
            TEX := TEX + ',' + ' Typ A: ';
      inc(i);
    end
    else ////////////////////////////////////
// Caption := s[i];
      if (s[i] = '0') and (s[i + 1] = '1') then // normaler 01
      begin
        TEX := TEX + ',' + ' Typ B: ';
        inc(i);
      end
      else ////////////////////////////////////
        if (s[i] = ',') then // and (s[i + 1] = ',') then // DOPPELTE Trenner finden
        begin
          inc(Menge);
        end
        else ////////////////////////////////////

          if Menge > 0 then
          begin
            Caption := s[i];
            if Menge = 1 then
              TEX := TEX + ',' + s[i]
            else
              TEX := TEX + s[i];
            Menge := 0; //
          end
          else
            TEX := TEX + s[i]; // LAST CHANGE


  end; // END WHILE
  Memo2.text := TEX;
  Memo1.text := S;
end; //
Mit Regex usw. kenn ich mich gar nicht aus. ...
Jan
Allen demnächst ein gutes 2023!
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#4

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 02:17
Überprüfe bitte mal, ob die inc(i) immer korrekt sind. Inc(i) entspricht halt i := i + 1. Aber bei x01 verarbeitest Du doch drei Zeichen, demnach müsstest Du hier auch i := i + 3 machen statt inc(i).
Bei 01 wäre es dann i := i + 2;

Bin mir nicht sicher, ob ich die Logik verstanden habe, es ist doch schon etwas zu früh - sorry spät
Quelltext hab' ich mal angepasst und ein bisserl kommentiert, aber nicht getestet.
Delphi-Quellcode:
procedure TForm1.Button9Click(Sender: TObject);
var Rest, s, TEX: string;
  Menge, Laenge, i: Integer;
begin
  // 8 8 88 888 X01
  S := '2,9,0171,,25,01640X0174,01747,23,,,,47X014747'; //

  S := '0,,25,01640X0174,01747,23,,,,47X014747'; //
  laenge := length(s);
  i := 1;
  Menge := 0;
  while i < laenge do begin
    if s[i] = '5then Caption := s[i];
    // -> x01
    if (s[i] = 'X') and (s[i + 1] = '0') then begin
      // wenn X01
      if (s[i + 2] = '1') then begin
        TEX := TEX + ',' + ' Typ A: ';
        inc(i,2);
      end;
    end else ////////////////////////////////////
    // Caption := s[i];
    // normaler 01
    if (s[i] = '0') and (s[i + 1] = '1') then begin
      TEX := TEX + ',' + ' Typ B: ';
      inc(i); // Sonst finden wir im nächsten Durchgang die 1 und geben sie aus.
    end else ////////////////////////////////////
    // DOPPELTE Trenner finden
    if (s[i] = ',') then begin // and (s[i + 1] = ',') then
      inc(Menge); // Zählt die Anzahl der , ???
    end else ////////////////////////////////////
    if Menge > 0 then begin
      // Hier kommen wir nur hin, wenn Menge > 0
      // und keine der anderen Bedingungen erfüllt ist.
      // Kann hier jemals ein Komma ausgegeben werden, dass vor X01 bzw. 01 steht?
      Caption := s[i];
(*
      if Menge = 1 then TEX := TEX + ',' + s[i]
      // Ist Menge jedoch > 1, wird kein Komma ausgegeben.
      // Geht uns da nicht bei mehreren Kommas was verloren?
      // Hier dürfte die Ursache für das fehlende Komma zwischen 0 und 25 liegen.
      else TEX := TEX + s[i];
*)

      // Würde hier nicht das reichen?
      // Egal wieviele wir gefunden haben, wir geben nur eins aus.
      TEX := TEX + ',' + s[i];
      Menge := 0; //
    end
    else TEX := TEX + s[i]; // LAST CHANGE
    inc(i);
  end; // END WHILE
  Memo2.text := TEX;
  Memo1.text := S;
end; //
Kennt Delphi 5 schon die Funktion AnsiReplaceText aus der Unit StrUtils?

Wenn ja, dann ließe sich das Problem eventuell so lösen:
Delphi-Quellcode:
s := '0,,25,01640X0174,01747,23,,,,47X014747';
s := AnsiReplaceText(s,'X01',' Typ A: ');
s := AnsiReplaceText(s,'01',' Typ B: ');
while Pos(',,',s) > 0 do begin
  s := AnsiReplaceText(s,',,',',');
end;
Ansonsten eventuell:
Delphi-Quellcode:
s := '0,,25,01640X0174,01747,23,,,,47X014747';
s := StringReplace(s,'X01',' Typ A: ',[rfReplaceAll, rfIgnoreCase]);
s := StringReplace(s,'01',' Typ B: ',[rfReplaceAll, rfIgnoreCase]);
while Pos(',,',s) > 0 do begin
  s := StringReplace(s,',,',',',[rfReplaceAll]);
end;
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
703 Beiträge
 
Delphi 12 Athens
 
#5

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 08:38
Ich würde da auch auf jeden Fall über eine Zeichenersetzungs-procedure gehen und da alle möglichen Fälle abarbeiten. Ist doch viel übersichtlicher.

Falls es in D5 noch kein ReplaceStr, AnsiReplaceText, StringReplace oder dergleichen gab, schreib dir einfach eine eigene. z.B.

Delphi-Quellcode:
function ReplaceString(StrOri, SuchStr, Repl:String):String;
var posi:integer;
begin
  posi:=pos(SuchStr, StrOri);
  while posi > 0 do begin
    StrOri:=copy(StrOri,1,posi-1)+ repl +
            copy(StrOri, posi+length(SuchStr), length(StrOri)-posi-length(SuchStr)+1);
    posi:=pos(SuchStr, StrOri);
  end;
  result:=StrOri;
end;
Und dann wie bereits vorgeschlagen:

Delphi-Quellcode:
s := '0,,25,01640X0174,01747,23,,,,47X014747';
s := ReplaceString(s,'X01',' Typ A: ');
s := ReplaceString(s,'01',' Typ B: ');
while Pos(',,',s) > 0 do begin
  s := ReplaceString(s, ',,', ',');
end;
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#6

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 08:46
Nach meiner Kenntnis gibt es in Delphi 5 sehr wohl die StringReplace-Funktion.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
490 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 09:45
Du läufst den kompletten String Zeichen für Zeichen durch und merkst Dir die Chars, an denen Du vorbeikommst.
Deine längste "Kennung" ist drei Zeichen lang (X01). Also brauchst Du nur drei Char-Variablen, die Du in dieser Schleife füllst/schiebst und prüfst, ob eine der Kennungen vorkommt. Die korrekten Zeichen und die korrigierten/ersetzten Zeichen schreibst Du in einen neuen (Ergebnis-)String.
Oder Du schaust Dir mal an, wie ein Parser arbeitet
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
relocate

Registriert seit: 26. Mai 2009
60 Beiträge
 
#8

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 10:15
Nach meiner Kenntnis gibt es in Delphi 5 sehr wohl die StringReplace-Funktion.
Die gibt es aber nicht ContainStr und ReplaceStr.

Leider stoße ich auch immer wieder auf so etwas. Gibt es eine Übersicht, ab wann welche Funktion in Delphi verfügbar ist. Auf den Emba-Seiten steht die Version so weit ich weiß nicht.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 11:20
Was lernen wir daraus? Backup und nie mit den original Daten arbeiten.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#10

AW: Zeichen in String ersetzen

  Alt 20. Dez 2016, 12:01
Falls es in D5 noch kein ReplaceStr, AnsiReplaceText, StringReplace oder dergleichen gab, schreib dir einfach eine eigene.

Oder such nach FastCode, da solltest Du auch das eine oder andere finden.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 22:34 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