Author: Jonas Bilinkevicius
I have a lot of the following lines:
02-07-01 12:05:30 XXX AAAAAA 100 BBBBB 666666 300
3700 -555.00 4.00
The only way to separate those items in the string is if there are more than 2
spaces between the items. There can also be 3 to 5 spaces actually. If there is one
space between strings - it is probably part of the bigger item as shown above:
'AAAAAA 100 BBBBB'. What would be the simplest way to split this string? I looked
at delimitedText but I am not sure of if it is going to help me.
Answer:
Solve 1:
See routine below. Is this data you have in a fixed-width column format produced by
another program? If so you cannot count on fields being separated by more than one
space! In fact you may have cases where there is no space between the fields
because a value fills the whole field width! For such files you have to use a
different strategy to parse the lines.
1 {SplitDataString:2 Dissect a string of items separated by more than one space character3 Param S contains the string to split, param list takes the items obtained from S4 Precondition: list <> nil5 6 Description:7 An item cannot start or end with a space but it may contain space characters flanked8 by non-space characters. The routine does not support multibyte character sets as it9 is implemented now.10 11 Created 28.7.2002 by P. Below}12 13 procedure SplitDataString(S: string; list: TStrings);
14 var15 startindex: Integer;
16 17 function HasNextItem: Boolean;
18 begin19 {We do not support a "Item" starting with a space!}20 while (startindex <= Length(S)) and (S[startindex] = #32) do21 Inc(startindex);
22 Result := startindex <= Length(S);
23 end;
24 25 function GetNextItem: string;
26 var27 endindex: Integer;
28 begin29 for endindex := startindex + 1 to Length(S) do30 begin31 if S[endindex] = ' ' then32 if S[endindex + 1] = ' ' then33 begin34 {found end of a Item}35 Result := Copy(S, startindex, endindex - startindex);
36 startindex := endindex + 2;
37 Exit;
38 end;
39 end;
40 {If we end here Item is the last in S}41 Result := Copy(S, startindex, maxint);
42 startindex := Length(S) + 1;
43 end;
44 45 begin46 Assert(Assigned(list));
47 {remove whitespace from start and end of string}48 S := Trim(S);
49 startindex := 1;
50 while HasNextItem do51 list.Add(GetNextItem);
52 end;
53 54 Example of use:
55 56 procedure TForm1.Button1Click(Sender: TObject);
57 begin58 memo1.clear;
59 SplitDataString('02-07-01 12:05:30 XXX AAAAAA 100 BBBBB 666666 300
60 ' -555.00 4.00', memo1.lines);
61 end;
62 63 64 Solve 2:
65 66 function SepSpacedOutStr(s: string): string;
67 var
68 i, x: integer;
69 begin
70 s := SysUtils.Trim(s);
71 if s <> '
72 begin73 SetLength(result, Length(s));
74 x := 0;
75 i := 1;
76 while i <= Length(s) do77 begin78 if (s[i] <> #32) or ((i < Length(s)) and (s[i + 1] <> #32)) then79 begin80 Inc(x);
81 result[x] := s[i];
82 end83 else84 begin85 if (i < Length(s)) and (s[i + 1] = #32) then86 begin87 Inc(x);
88 result[x] := ',';
89 Inc(x);
90 result[x] := #32;
91 while (i < Length(s)) and (s[i + 1] = #32) do92 Inc(i);
93 end;
94 end;
95 Inc(i);
96 end;
97 SetLength(result, x);
98 end99 else100 result := '';
101 end;