FAQ » Tekst

Jak rozdzielić łańcuch tekstowy wg. jakiegoś znaku

  • 2006-02-05 12:10
  • 5 komentarzy
  • 5562 odsłony
  • Oceń ten tekst jako pierwszy
Osoby, które korzystają z Perla lub PHP znają zapewne funkcje Split (lub Explode), która umożliwia rozdzielenie łańcucha tekstowego na kilka części, według konkretnego znaku. Niestety w Delphi dla Win32 nie ma funkcji realizującej to zadanie. Do tego celu można użyć modułu zaprezentowanego w tej wskazówce.

Rozwiązanie #1


Oto moduł, który zawiera funkcje Split, dzięki której możesz rozdzielić łańcuch tekstowy:

(*
 
           b4p Project v. 1.1
           -----------
           Utworzenie pliku: 28.06.2002 00:28
           Autorzy: Adam Boduch [[email protected]]
 
           -----------
           Modul SplitUnit
           http://4programmers.net
*)
 
unit SplitUnit;
 
(*
   Modul ten zawiera procedure Split, ktora rozdziela dane w Stringu wg. okreslonego
   znaku. 
*)
 
interface
 
uses Windows;
 
var
  KeyChar : Char = ' '; // znak wg. bedzie nastepywac rozdzielenie
 
type
  TSplit = array of String; // nowy typ danych okreslajacy tablice stringow
 
  procedure Split(Value : String; var Output : TSplit); // funkcja rozdzielajaca Split
 
implementation
 
procedure Split(Value : String; var Output : TSplit);
var
  iCount : Integer;
 
  procedure Explode;
  var
    Found : Integer;
  begin
    SetLength(Output, iCount+1);
    Found := Pos(KeyChar, Value); // najpierw nastepuje odnalezienie szukanego znaku
 
   { pozniej za pomoca funkcji Copy nastepuje skopiowanie czesci danych do elementu
     tablicy }
    Output[iCount] := Copy(Value, 1, Found -1);
    Delete(Value, 1, Found); // skopiowane juz dane zostaja ze stringa usuniete
    Inc(iCount);  // zwiększenie licznika
 
    Found := Pos(KeyChar, Value); // ponowne odszukanie znaku KeyChar
    if Found > 0 then Explode; // w razie znaleienia ponownie wywolaj te procedure
  end;
 
begin
{
   Funkcja Split powoduje rozdzielenie danych ze stringa na kilka(kilkanascie)
   elementow i przypisanie jej do tablicy Output. Procedura ta wywoluje inna - Explode,
   ktora to jest procedura rekurencyjna (o rekurencji mozesz poczytac m.in na stronie
   www.4programmers.net/Algorytmy ) i to ona ma kluczowe zadanie rozdzielenie lancucha.
}
  iCount := 0;
  SetLength(Output, 1); // okreslenie liczby elementow tablicy dynamicznej
  Insert(KeyChar, Value, Length(Value)+1); // dodanie na samym koncu lancucha ze stalej KeyChar
 
  Explode; // wywolanie funkcji rekurencyjnej
end;
 
 
end.


Przykład użycia:

var
  S : String;
  Output : TSplit;
begin
  S := DupeString('ala ', 1000); // utworzenie przykładowego ciągu
 
  Split(S, Output); // tablica Output zawiera rozdzielony ciąg
end.


Rozwiązanie #2


Można również wykorzystać funkcję przedstawioną poniżej, która według testów działa znacznie szybciej. Rozdzielone łańcuchy przypisywane są jako elementy klasy TStrings:

procedure Split(Str: string;  SubStr: string; List: TStrings);
var
  I: Integer;
  S, Tmp: string;
begin
  List.Clear;
  S := Str;
  while Length(S) > 0 do
  begin
    I := Pos(SubStr, S);
    if I = 0 then
    begin
      List.Add(S);
      S := '';
    end
    else
    begin
      if I = 1 then
      begin
        List.Add('');
        Delete(S, 1, Length(SubStr));
      end
      else
      begin
        Tmp := S;
        Delete(Tmp, I, Length(Tmp));
        List.Add(Tmp);
        Delete(S, 1, I + Length(SubStr) - 1);
        if Length(S) = 0 then
          List.Add('');
      end;
    end;
  end;
end;


Parametr S musi zawierać ciąg do rozdzielenia natomiast SubStr - ciąg na podstawie którego łańcuch zostanie rozdzielony.

Rozwiązanie nr #3


Funkcja ExtractStrings zadeklarowana jest w module Classes. Jej użycie jest proste. Poniższy kod rozdziela łancuch na podstawie znaków spacji:

procedure TMyForm.MyButtonClick(Sender: TObject);
const
  Foo = 'To jest łańcuch który zostanie rozdzielony';
var
  S : TStrings;
  i : Integer;
begin
  S := TStringList.Create;
  ExtractStrings([' '], [], Foo, S);
 
  for I := 0 to S.Count -1 do
    Memo1.Lines.Add(S[i]);
 
  S.Free;
end;


Zobacz też:

5 komentarzy

Henryk555 2016-11-24 22:02

Adam dziękuję,
  Co prawda 'Explode' mam w troszkę innej wersji ... (także z php) ale... szukam kodu dla implode plus example jak to użyć. Masz może jakieś sugestie odnośnie?
Pozdrawiam Henryk

pq 2006-05-20 00:26

" Niestety w Delphi dla Win32 nie ma funkcji realizującej to zadanie."

Adam, doucz sie:-)

ExtractStrings jest.

explosive 2004-10-27 16:38

Adam, co my bysmy bez ciebie zrobili :)

sadzik 2003-11-03 20:02

adam dzieki za kodzik