Jak rozdzielić łańcuch tekstowy wg. jakiegoś znaku
Adam Boduch
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ż:
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
" Niestety w Delphi dla Win32 nie ma funkcji realizującej to zadanie."
Adam, doucz sie:-)
ExtractStrings jest.
inne rozwiązanie: http://www.swissdelphicenter.ch/torry/showcode.php?id=1326
Adam, co my bysmy bez ciebie zrobili :)
adam dzieki za kodzik