Author: Ernesto De Spirito
A function that splits a string in parts separated by a substring and returns the
parts in a StringList
Answer:
Solve 1:
The following functions split a string in parts separated by a substring and return
the parts in a string list that may be passed as third parameter or created by the
function (and in this latter case it must be freed by the caller):
1 interface
2
3 uses classes;
4
5 function SplitStrings(const str: string;
6 const separator: string = ',';
7 Strings: TStrings = nil): TStrings;
8 function AnsiSplitStrings(const str: string;
9 const separator: string = ',';
10 Strings: TStrings = nil): TStrings;
11
12 implementation
13
14 uses sysutils;
15
16 function SplitStrings(const str: string; const separator: string;
17 Strings: TStrings): TStrings;
18 // Fills a string list with the parts of "str" separated by
19 // "separator". If Nil is passed instead of a string list,
20 // the function creates a TStringList object which has to
21 // be freed by the caller
22 var
23 n: integer;
24 p, q, s: PChar;
25 item: string;
26 begin
27 if Strings = nil then
28 Result := TStringList.Create
29 else
30 Result := Strings;
31 try
32 p := PChar(str);
33 s := PChar(separator);
34 n := Length(separator);
35 repeat
36 q := StrPos(p, s);
37 if q = nil then
38 q := StrScan(p, #0);
39 SetString(item, p, q - p);
40 Result.Add(item);
41 p := q + n;
42 until q^ = #0;
43 except
44 item := '';
45 if Strings = nil then
46 Result.Free;
47 raise;
48 end;
49 end;
50
51 function AnsiSplitStrings(const str: string; const separator: string;
52 Strings: TStrings): TStrings;
53 // Fills a string list with the parts of "str" separated by
54 // "separator". If Nil is passed instead of a string list,
55 // the function creates a TStringList object which has to
56 // be freed by the caller
57 // ANSI version
58 var
59 n: integer;
60 p, q, s: PChar;
61 item: string;
62 begin
63 if Strings = nil then
64 Result := TStringList.Create
65 else
66 Result := Strings;
67 try
68 p := PChar(str);
69 s := PChar(separator);
70 n := Length(separator);
71 repeat
72 q := AnsiStrPos(p, s);
73 if q = nil then
74 q := AnsiStrScan(p, #0);
75 SetString(item, p, q - p);
76 Result.Add(item);
77 p := q + n;
78 until q^ = #0;
79 except
80 item := '';
81 if Strings = nil then
82 Result.Free;
83 raise;
84 end;
85 end;
Examples:
86 procedure TForm1.Button1Click(Sender: TObject);
87 begin
88 SplitStrings(Edit1.Text, ', ', ListBox1.Items);
89 end;
90
91 procedure TForm1.Button2Click(Sender: TObject);
92 var
93 Parts: TStrings;
94 begin
95 Parts := nil;
96 try
97 Parts := SplitStrings(Edit1.Text, ', ');
98 ShowMessage('First part is "' + Parts[0] + '"');
99 finally
100 Parts.Free;
101 end;
102 end;
You can see an example using a dynamic array instead of a StringList in a separate
article "Splitting a string in an dynamic arraydkb://531023430".
Solve 2:
Shorten way:
103 function SplitStrings(const str: string; const separator: string;
104 Strings: TStrings): TStrings;
105 // Fills a string list with the parts of "str" separated by
106 // "separator". If Nil is passed instead of a string list,
107 // the function creates a TStringList object which has to
108 // be freed by the caller
109 begin
110 if Strings = nil then
111 Result := TStringList.Create
112 else
113 Result := Strings;
114
115 //This replaces the separators in str with CRLF so as to fit the format of a
116 stringlist.
117 Result.Text := StringReplace(str, separator, #13#10, [rfReplaceAll]);
118 end;
|