Rozdzielanie ciągów i uzyskanie pustego ciągu

0

Witam,
mam dane, które są od siebie oddzielone znakiem "|". Rozdzielam je poprzez funkcję

ExtractStrings

.
Wszystko działa prawidłowo do czasu gdy natrafiam na puste miejsce, a chcę je pobrać z tekstu. Dla przykładu: aa|bb|cc||dd. Jeśli rozdzielam tekst to w tym ciągu jest to puste miejsce pomijane. Jeśli wrzucę to do np.: memo to otrzymam coś takiego:
aa
bb
cc
dd
a chciałbym otrzymać:
aa
bb
cc

dd.
Jak mogę taki efekt osiągnąć? Każde dane mają określoną dla danej linii ilość takich tekstów rozdzielonych znakim|. Jeśli jeden mi wypadnie poprzez puste dane to automatycznie zmniejszy się ilość, a program wywali błąd. Proszę o pomoc. Dziękuję

0

Poradziłem sobie z tym w sposób trochę "na około". Po prostu po wczytaniu danych do zmiennej zamieniam znaki "||" czyli te puste na "| |" ze spacją - sprawdza się. Jeśli ktoś zna lepsze rozwiązanie to będzie mile widziane.

0

Jeśli ktoś zna lepsze rozwiązanie to będzie mile widziane.

Można napisać swoją baardzo prostą funkcję która to zrobi, czyż nie?

function Explode(s:ansistring;delim:char='|'):TStrings;
var
i:integer;
begin
  result:=TStringList.Create();
  while length(s)=0 do
  begin
  i:=Pos(delim,s);
  if i=0 then i:=length(s)+1;
  result.Add(copy(s,1,i-1));
  s:=copy(s,i+1,length(s));
  end;//Nie formatujemy, oszczędzamy spację.
end;

(Pisane na szybko, may contain nuts).

0

Można t3eż skorzystać z gotowego rozwiązania:

var
  s: TStringList;
begin
  s:= TStringList.Create;
  try
  s.Delimiter:= '|';
  s.DelimitedText:= 'aa|bb|cc||dd';
  ListBox1.Items.Assign(s);
  finally
  s.Free;
  end;
end;
0
s.DelimitedText:= 'aa|bb|cc||dd';

da taki sam efekt jak już uzyskałem czyli pomiędzy znakami "|" i "|" będzie puste miejsce - nie spacja bo zanim zacząłem zamieniać znaki to próbowałem tego. Jak na razie moje rozwiązanie z podmianą znaków sprawdza się. Dzięki

0

Można to zrobić bardzo prosto na pętli for .. to .. do:

procedure SplitString(Line: String; Separator: Char; var List: TStrings);
var
  iLast, I: Word;
begin
  if Line <> '' then
    begin
      Line := Line + Separator;
      iLast := 1;

      for I := 1 to Length(Line) do
        if Line[I] = Separator then
          begin
            List.Add(Copy(Line, iLast, I - iLast));
            iLast := I + 1;
          end;
    end;
end;

Dzieląc np. taką linię:

const
  Line = 'aa|bb||cc||dd|ee';

uzyskamy 7 części:

"aa"
"bb"
""
"cc"
""
"dd"
"ee"

oczywiście bez apostrofów (""), dodane tylko po to, by było widać, że odstęp w wierszach to pusta wartość z listy; Kilka razy musiałem podzielić łańcuch właśnie uwzględniając puste wartości i ta procedura nigdy mnie nie zawiodła; Dostosuj ją pod swoje wymagania;

0

U mnie (i raczej nigdzie nie powinien) ten kod nie powoduje błędu:

var
  s: TStringList;
  test: string;
begin
  s:= TStringList.Create;
  try
  s.Delimiter:= '|';
  s.DelimitedText:= 'aa|bb|cc||dd';
  test:= s.Strings[3]; //akurat będzie pusty
  ShowMessage(test);
  finally
  s.Free;
  end;
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1