Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   führende null entfernen (https://www.delphipraxis.net/197358-fuehrende-null-entfernen.html)

Dr. Jack 1. Aug 2018 14:40

führende null entfernen
 
Hallo zusammen,

ich bekomme es leider nicht hin, eine führende Null bzw führende Nullen aus einem String zu entfernen.
Ich habe z.B. diese Artikelnummer: 00850046. Diese soll zu 850046 geändert werden.
Code:
 For i := 1 to Length(nr_pzn_bereinigt) do
           begin
           If nr_pzn_bereinigt[i] = '0' Then Delete(nr_pzn_bereinigt, i, 1)
           Else
            Break;
Ich dachte, er geht diesen String so lange durch bis er auf keine Null mehr trifft und bricht dann ab.
Geht leider nicht.

Kann jemand helfen?

jobo 1. Aug 2018 14:45

AW: führende null entfernen
 
Ja, macht er wahrscheinlich auch, direkt bei StringElement[0] wo die Länge des Strings drin steht.

Dalai 1. Aug 2018 14:47

AW: führende null entfernen
 
Sofern sichergestellt ist, dass sich im String ausschließlich Ziffern befinden, wäre StrToInt mit einem anschließenden Zurückwandeln mit IntToStr nicht einfacher?

Grüße
Dalai

Neutral General 1. Aug 2018 14:51

AW: führende null entfernen
 
Zitat:

Zitat von jobo (Beitrag 1409359)
Ja, macht er wahrscheinlich auch, direkt bei StringElement[0] wo die Länge des Strings drin steht.

Nein, die Schleife geht ab 1 los.
Das Problem ist, dass der String kürzer wird, und die Schleife so quasi "verrutscht"

Schleifendurchlauf:

i=1:
00850046 => 0850046

i=2:
0850046

Die zweite 0 hat er quasi jetzt schon übersprungen weil sich die 2. 0 jetzt nach dem Löschen der ersten auch an Position 1 befindet aber die Schleife jetzt schon bei i=2 ist.

bernau 1. Aug 2018 14:53

AW: führende null entfernen
 
Zitat:

Zitat von Dr. Jack (Beitrag 1409358)
Hallo zusammen,

ich bekomme es leider nicht hin, eine führende Null bzw führende Nullen aus einem String zu entfernen.
Ich habe z.B. diese Artikelnummer: 00850046. Diese soll zu 850046 geändert werden.
Code:
 For i := 1 to Length(nr_pzn_bereinigt) do
           begin
           If nr_pzn_bereinigt[i] = '0' Then Delete(nr_pzn_bereinigt, i, 1)
           Else
            Break;
Ich dachte, er geht diesen String so lange durch bis er auf keine Null mehr trifft und bricht dann ab.
Geht leider nicht.

Kann jemand helfen?

In deinem Code löscht du das erste Zeichen und prüfst dann das zweite Zeichen. Das ursprünglich zweite Zeichen wird aber zum ersten Zeichen, weil ja gelöscht wurde. Und du prüfst im zweiten Durchgang so gesehen das ursprünglich dritte Zeichen. u.s.w.


(Edit: Da war jemand schneller)

Delphi.Narium 1. Aug 2018 14:54

AW: führende null entfernen
 
Delphi-Quellcode:
nr_pzn_bereinigt[i] := IntToStr(StrToInt(nr_pzn_bereinigt[i]));
geht, solange nur Ziffern vorkommen, kommt mal ein Buchstabe (oder besser einen Nichtziffer) geht's schief.

Delphi-Quellcode:
while Copy(nr_pzn_bereinigt[i],1,1) = '0' do begin
  nr_pzn_bereinigt[i] := Copy(nr_pzn_bereinigt[i],2,Length(nr_pzn_bereinigt[i]));
end;
Beispiel zu Deinem Vorgehen:

i ist 1
00850046
1. Zeichen = '0'
0850046 bleibt dann übrig

i wird nun 2
zweites Zeichen ist nun 8, da das erste Zeichen entfernt wurde.
0850046 bleibt dann übrig

i wird nun 3
drittest Zeichen = 5
0850046 bleibt dann übrig

i wird nun 4
viertes Zeichen = 0
085046 bleibt dann übrig

i wird nun 5
fünftes Zeichen = 4
085046 bleibt dann übrig

i wird nun 6
fünftes Zeichen = 6
085046 bleibt dann übrig

Das ist eher so 'ner Art zufälliges Nullenentfernen, abhängig davon wieviele Nullen vorher dort waren und an welcher Position sie sich befinden.

Neutral General 1. Aug 2018 14:55

AW: führende null entfernen
 
@Delphi.Narium: Deine Simulation stimmt nicht ganz, weil er bei i=2 mit break rausspringen würde, weil '8' <> '0'

KodeZwerg 1. Aug 2018 14:57

AW: führende null entfernen
 
In Unit JclStrings könnte man
Delphi-Quellcode:
StrTrimCharLeft('00850046', '0');
aufrzufen um einen "850046" String zu erhalten, ansonsten schließe ich mich Dalei an, hier ein mini Beispiel dazu:
Delphi-Quellcode:
function EntferneNullen(const Input: String): String;
begin
  Result := IntToStr(StrToIntDef(Input,0));
end;

SProske 1. Aug 2018 14:57

AW: führende null entfernen
 
Wenn die Version im Profil stimmt, könnte man das natürlich auch über

Delphi-Quellcode:
nr_pzn_bereinigt := nr_pzn_bereinigt.TrimLeft(['0']);
lösen

Delphi.Narium 1. Aug 2018 15:00

AW: führende null entfernen
 
Zitat:

Zitat von Neutral General (Beitrag 1409364)
@Delphi.Narium: Deine Simulation stimmt nicht ganz, weil er bei i=2 mit break rausspringen würde, weil '8' <> '0'

Ja schon, und deshalb fällt der Fehler nicht auf. Wenn man mal ohne break arbeitet, sieht man, dass man auch mittendrinnen ggfls. noch die eine oder andere 0 entfernen würde, was dann den Fehlergrund offensichtlich machen würde.

Dr. Jack 1. Aug 2018 15:02

AW: führende null entfernen
 
Zitat:

Zitat von SProske (Beitrag 1409366)
Wenn die Version im Profil stimmt, könnte man das natürlich auch über

Delphi-Quellcode:
nr_pzn_bereinigt := nr_pzn_bereinigt.TrimLeft(['0']);
lösen

genau Trimleft super. danke das war die Lösung! Daumen hoch!

KodeZwerg 1. Aug 2018 15:25

AW: führende null entfernen
 
Ich habe auch noch etwas herumgespielt, sowas kam dabei raus:
Delphi-Quellcode:
function RemLeadChar(const Input: string; const LeadChar: Char): string;
var
  i, ii: Integer;
begin
  ii := 0;
  if Length(Input) > 0 then // ein zeichen minimum um weiter zu kommen
   if Input[1] = LeadChar then // fängt String nicht mit LeadChar an gibts nichts zu tun
    for i := 1 to Length(Input) do // komplette stringlänge abarbeiten initialisieren
      if Input[i] = LeadChar then ii := i else Break; // kommt vorne ein LeadChar vor Position merken
    if ii > 0 then Result := Copy(Input, ii+1, Length(Input)) // entweder anfang verwerfen
     else Result := Input; // oder eingabe zurück
end;
Beispiel Aufruf:
Delphi-Quellcode:
Memo1.Lines.Add(RemLeadChar(Edit1.Text,'0'));

Neutral General 1. Aug 2018 15:30

AW: führende null entfernen
 
Wie wärs einfach hiermit?
Delphi-Quellcode:
function RemLeadChar(const Input: string; const LeadChar: Char): string;
begin
  if Length(Input) > 0 then
  begin
    Result := Input;
    while (Result[1] = LeadChar) do
      delete(Result, 1, 1);
  end
  else
    Result := '';
end;

Delphi.Narium 1. Aug 2018 15:38

AW: führende null entfernen
 
oder
Delphi-Quellcode:
function RemLeadChar(const Input: string; const LeadChar: Char): string;
begin
  Result := Input;
  if Length(Result) > 0 then while Result[1] = LeadChar do delete(Result, 1, 1);
end;

Zacherl 1. Aug 2018 15:39

AW: führende null entfernen
 
Btw: Das mehrfache
Delphi-Quellcode:
Delete
ist ziemlich imperformant. Ich würde erstmal in einer Schleife die Stelle der ersten nicht-Null suchen und danach per
Delphi-Quellcode:
Delete
alles bis zu diesem Index am Stück entfernen.

jobo 1. Aug 2018 15:39

AW: führende null entfernen
 
Zitat:

Zitat von Neutral General (Beitrag 1409361)
Zitat:

Zitat von jobo (Beitrag 1409359)
Ja, macht er wahrscheinlich auch, direkt bei StringElement[0] wo die Länge des Strings drin steht.

Nein, die Schleife geht ab 1 los.
Das Problem ist, dass der String kürzer wird, und die Schleife so quasi "verrutscht"

Ja, Du hast Recht, ich hab gepennt.

KodeZwerg 1. Aug 2018 15:42

AW: führende null entfernen
 
Das ist ja das schöne bei Delphi, jeder kann seine persönliche Note einbringen :love:
Müssen viele LeadChars entfernt werden ist mein Vorschlag bestimmt nen takken schneller ^_^

Mini Upgrade vs Leerstrings
Delphi-Quellcode:
function RemLeadChar(const Input: string; const LeadChar: Char): string;
var
  i, ii: Integer;
begin
  ii := 0;
  if Length(Input) > 0 then // ein zeichen minimum um weiter zu kommen
   if Input[1] = LeadChar then // fängt String nicht mit LeadChar an gibts nichts zu tun
    for i := 1 to Length(Input) do // komplette stringlänge abarbeiten initialisieren
      if Input[i] = LeadChar then ii := i else Break; // kommt vorne ein LeadChar vor Position merken
  if ii > 0 then Result := Copy(Input, ii+1, Length(Input)) // entweder anfang verwerfen
   else Result := Input; // oder eingabe zurück
  if Result = '' then Result := LeadChar; // falls input leer oder nur aus LeadChars bestand, gib wenigstens ein LeadChar zurück
end;
und noch ein Vorschlag zu dem While Delete
Delphi-Quellcode:
function RemDelLeadChar(const Input: string; const LeadChar: Char): string;
var
  i: Integer;
begin
  i := 1;
  Result := Input;
  if ((Length(Input) > 0) and (Input[1] = LeadChar)) then
  begin
    while (Input[i] = LeadChar) do inc(i);
    Delete(Result, 1, i-1);
  end;
  if Result = '' then Result := LeadChar;
end;

Redeemer 1. Aug 2018 18:05

AW: führende null entfernen
 
for-Schleifen, die etwas löschen (wodurch die Nachfolger aufrücken), einfach immer mit downto machen. Klappt übrigens auch nicht mit for-in-Schleifen.

Neutral General 1. Aug 2018 18:15

AW: führende null entfernen
 
Zitat:

Zitat von Redeemer (Beitrag 1409399)
for-Schleifen, die etwas löschen (wodurch die Nachfolger aufrücken), einfach immer mit downto machen. Klappt übrigens auch nicht mit for-in-Schleifen.

"Einfach downto" ist in dem Fall aber leider nicht so einfach, weil er nur die '0'en am Anfang des Strings entfernen will und mit ner downto-Schleife ist es etwas problematisch festzustellen ob weiter vorne (nur) noch '0'en sind oder ob dazwischen jetzt noch ne andere Zahl kommt und man daher die aktuelle '0' nicht löschen darf.

KodeZwerg 1. Aug 2018 18:19

AW: führende null entfernen
 
Kann ich ein Beispiel bekommen wo der genannte Code nicht funktioniert? Ich habe es mit allerlei kram getestet ohne auf Fehler zu stossen. Ein Delete bzw Cut kommt bei mir ja auch nur einmal vor.

p80286 1. Aug 2018 18:20

AW: führende null entfernen
 
@Redeemer

Dafür müßtest Du das erste nicht 0 suchen, und dann kannst Du es am Stück löschen.

Delphi-Quellcode:
i:=0;
if length(mystring)>0 then begin
  repeat
    if mystring[i+1]<>'0' then inc (i,1);
  until (mystring[i+1]<>'0') or (i>=length(mystring));
  if i>0 then delete(mystring,1,i);
end;
Gruß
K-H

@KodeZwerg
Dein zweites Beispiel kann Ärger machen, da Du die Länge des String nicht berücksichtigst.

Redeemer 1. Aug 2018 18:30

AW: führende null entfernen
 
Zitat:

Zitat von Neutral General (Beitrag 1409401)
Zitat:

Zitat von Redeemer (Beitrag 1409399)
for-Schleifen, die etwas löschen (wodurch die Nachfolger aufrücken), einfach immer mit downto machen. Klappt übrigens auch nicht mit for-in-Schleifen.

"Einfach downto" ist in dem Fall aber leider nicht so einfach, weil er nur die '0'en am Anfang des Strings entfernen will und mit ner downto-Schleife ist es etwas problematisch festzustellen ob weiter vorne (nur) noch '0'en sind oder ob dazwischen jetzt noch ne andere Zahl kommt und man daher die aktuelle '0' nicht löschen darf.

Ach ja, stimmt.

KodeZwerg 1. Aug 2018 19:05

AW: führende null entfernen
 
Zitat:

Zitat von p80286 (Beitrag 1409403)
Dein zweites Beispiel kann Ärger machen, da Du die Länge des String nicht berücksichtigst.

Ich versuche gerade Nachzuvollziehen an welcher Stelle es böse ausgehen könnte, deswegen kommentare rangeklebt damit ihr seht was ich anstellen wollte, vielleicht ist umsetzung falsch
Delphi-Quellcode:
function RemDelLeadChar(const Input: string; const LeadChar: Char): string;
var
  i: Integer;
begin
  i := 1; // String Index auf 1 (der erste) setzen
  Result := Input; // result mit input initialisieren
  if ((Length(Input) > 0) and (Input[1] = LeadChar)) then // wenn länge +1 und mit LeadChar anfängt dann...
  begin // block anfangen damit delete korrekt ausgeführt wird
   while (Input[i] = LeadChar) do inc(i); // solange leadchar vorne [i] vorkommt gib +1 auf i
   Delete(Result, 1, i-1); // da wenigstens ein LeadChar vorkam kann man bedenkenlos ausführen
  end; // ende vom länge/leadchar block
  if Result = '' then Result := LeadChar; // falls string leer ist, gib wenigstens ein leadchar wieder
end;

Hobbycoder 1. Aug 2018 19:12

AW: führende null entfernen
 
Ein hätte ich auch noch:
Delphi-Quellcode:
function RemoveLeftZero(input: string): string;
var
  i: integer;
begin
  result:='';
  for i:=1 to length(input) do
    if result<>'' then
      result:=result+input[i]
    else
      if input[i]<>'0' then result:=result+input[i];
end;
Performance ist aber sicher nicht die beste, aber darum geht's hier ja nicht.

Hobbycoder 1. Aug 2018 19:18

AW: führende null entfernen
 
Und noch einen:
Delphi-Quellcode:
function RemoveLeftZero(input: string): string;
var
  i: integer;
begin
  result:=input;
  for i:=1 to length(input) do
    if input[i]='0' then
      delete(result, 1, 1) else
      Break;
end;
Schleife muss halt bei '0805668' nur zweimal durchlaufen.

Neutral General 1. Aug 2018 19:35

AW: führende null entfernen
 
KodeZwerg das Problem ist diese Zeile:
Delphi-Quellcode:
while (Input[i] = LeadChar) do inc(i);


Das kann bei einem String der komplett aus LeadChars besteht in die Hose gehen, weil zumindest mal Input[Length(Input)+1] gecheckt wird, was mit ein bisschen Pech knallen kann.
Deswegen müsste es
Delphi-Quellcode:
while (i <= Length(Input)) and (Input[i] = LeadChar) do inc(i);

heißen

KodeZwerg 1. Aug 2018 19:41

AW: führende null entfernen
 
Zitat:

Zitat von Neutral General (Beitrag 1409417)
Deswegen müsste es
Delphi-Quellcode:
while (i <= Length(Input)) and (Input[i] = LeadChar) do inc(i);

:thumb::thumb: Danke fürs Nase drauf stubsen!

Ps: Bei meinen Samples könnte man die schleifen auch ab zweite position laufen lassen um einen doppelten check zu vermeiden aber da fehlt dann erst mal ein längen check ob überhaupt content eine länge von 2 besitzt. Ich wollte halt string operationen auf einen einzigen manipulator bringen, jeweils basierend auf einem count index-wert.

KodeZwerg 1. Aug 2018 20:07

AW: führende null entfernen
 
Zitat:

Zitat von p80286 (Beitrag 1409403)
Delphi-Quellcode:
i:=0;
if length(mystring)>0 then begin
  repeat
    if mystring[i+1]<>'0' then inc (i,1);
  until (mystring[i+1]<>'0') or (i>=length(mystring));
  if i>0 then delete(mystring,1,i);
end;

Das führt bei mir zu einer Endlos-Schleife, aber so klappts:
Delphi-Quellcode:
function DelLeadChar(const Input: string; const LeadChar: Char): string;
var
  i: Integer;
begin
  i:=0;
  Result := Input;
  if length(Input)>0 then
   begin
     repeat
       if Input[i+1]=LeadChar then inc (i,1);
//       if Input[i+1]<>LeadChar then inc (i,1); // nicht gut ^_^
     until (Input[i+1]<>LeadChar) or (i>=length(Input));
     if i>0 then delete(Result,1,i);
   end;
end;

DeddyH 1. Aug 2018 20:10

AW: führende null entfernen
 
Ich hätte mittels Schleife den Index des ersten Nicht-Null-Zeichens ermittelt und ab da einfach kopiert.

p80286 1. Aug 2018 20:10

AW: führende null entfernen
 
:oops:
Typischer Fall von das eine Denken und das Andere tippen!

Gruß
K-H

p80286 1. Aug 2018 20:14

AW: führende null entfernen
 
Zitat:

Zitat von DeddyH (Beitrag 1409421)
Ich hätte mittels Schleife den Index des ersten Nicht-Null-Zeichens ermittelt und ab da einfach kopiert.

Da war irgendwas mit umkopieren der Daten in bereits allokierten Speicher (delete), aber unsere Assembler Freaks wissen da besser Bescheid.

Gruß
K-H

Neutral General 1. Aug 2018 20:18

AW: führende null entfernen
 
Zitat:

Zitat von p80286 (Beitrag 1409423)
Zitat:

Zitat von DeddyH (Beitrag 1409421)
Ich hätte mittels Schleife den Index des ersten Nicht-Null-Zeichens ermittelt und ab da einfach kopiert.

Da war irgendwas mit umkopieren der Daten in bereits allokierten Speicher (delete), aber unsere Assembler Freaks wissen da besser Bescheid.

Das ist doch was KodeZwerg als aller erstes gepostet hat oder nicht?

KodeZwerg 1. Aug 2018 20:18

AW: führende null entfernen
 
Zitat:

Zitat von DeddyH (Beitrag 1409421)
Ich hätte mittels Schleife den Index des ersten Nicht-Null-Zeichens ermittelt und ab da einfach kopiert.

Weicht Deine Methode von den gezeigten ab? (Vielleicht mittels Pointer-Operation fällt mir auf die schnelle noch ein)
Zitat:

Zitat von Neutral General (Beitrag 1409424)
Das ist doch was KodeZwerg als aller erstes gepostet hat oder nicht?

Ja. Das erschien mir die performanteste Umsetzung.
Delphi-Quellcode:
function RemLeadChar(const Input: string; const LeadChar: Char): string;
var
  i, ii: Integer;
begin
  ii := 0;
//  if Length(Input) > 0 then // ein zeichen minimum um weiter zu kommen // den check kann man sich sparen
//   if Input[1] = LeadChar then // fängt String nicht mit LeadChar an gibts nichts zu tun // den check kann man sich sparen
    for i := 1 to Length(Input) do // komplette stringlänge abarbeiten initialisieren
      if Input[i] = LeadChar then ii := i else Break; // kommt vorne ein LeadChar vor Position merken
  if ii > 0 then Result := Copy(Input, ii+1, Length(Input)) // entweder anfang verwerfen
   else Result := Input; // oder eingabe zurück
  if Result = '' then Result := LeadChar; // falls input leer oder nur aus LeadChars bestand, gib wenigstens ein LeadChar zurück
end;

DeddyH 1. Aug 2018 20:52

AW: führende null entfernen
 
Auf dem Tablet direkt im Editor getippt, daher komplett aus dem Kopf:
Delphi-Quellcode:
function StrippedLeft(const Input: String; const Leading: Char): String;
var
  i, idx: integer;
begin
  idx := 0;
  for i := 1 to Length(Input) do
    if Input[i] <> Leading then
      begin
        idx := i;
        Break;
      end;
  if idx > 0 then
    Result := Copy(Input, idx)
  else
    Result := ´´;
end;

KodeZwerg 1. Aug 2018 21:12

AW: führende null entfernen
 
Zitat:

Zitat von DeddyH (Beitrag 1409427)
Auf dem Tablet direkt im Editor getippt, daher komplett aus dem Kopf

Habe zwei überflüssige checks entfernt, nun schauts sogut wie gleich aus, ich geh halt mit break und worauf es reagiert anders um.

Rollo62 2. Aug 2018 06:33

AW: führende null entfernen
 
Was spricht eigentlich gg. das offizielle TrimLeft (siehe dem akzeptierten Vorschlag von SProske ) ?

DeddyH 2. Aug 2018 06:48

AW: führende null entfernen
 
Gar nichts, aber die nötige Überladung ist ja AFAIK erst mit dem StringHelper eingeführt worden, ältere Delphi-Versionen dürften das noch nicht kennen.

Jasocul 2. Aug 2018 07:00

AW: führende null entfernen
 
Da mir nach meinem ersten Kaffee danach war:
Delphi-Quellcode:
function DelLeadStr(LeadStr : String; InpStr : String) : String;
var
  vLeadStr : String;
begin
  vLeadStr := LeadStr;
  while Pos(vLeadStr, InpStr) = 1 do
  begin
    vLeadStr := vLeadStr + LeadStr;
  end;
  Delete(InpStr, 1, Length(vLeadStr) - Length(LeadStr));
  Result := InpStr;
end;
Vorteil:
- Kein Zugriff per Index auf den String --> Damit leicht umstellbar auf WideString (oder kann man da auch über den Index zugreifen?)
- Keine Längenprüfung erforderlich
- Auch führende Strings (also nicht nur ein Zeichen) können behandelt werden
Nachteil:
- Vermutlich etwas langsamer

Neutral General 2. Aug 2018 08:32

AW: führende null entfernen
 
Man kann auch bei WideStrings ganz normal ohne Probleme über den Index zugreifen.

Jasocul 2. Aug 2018 09:49

AW: führende null entfernen
 
Zitat:

Zitat von Neutral General (Beitrag 1409460)
Man kann auch bei WideStrings ganz normal ohne Probleme über den Index zugreifen.

Danke für die Info


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:43 Uhr.
Seite 1 von 2  1 2      

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