2.
- -. - , . , , . ( CSV (comma-separated values - , ).) ( !). ( ). - , .
CSV.
Julian,Bucknall,,43,"Author, and Columnist"
. [Julian] [Bucknall], , - [43], - [Author, and Columnist]. ( , .)
, , , . , CSV. -, , - (, , CSV) , . , , ( ). , , , , , ["Author] [and Columnist"]. , , , ( ). , .
- . . 2 . FieldStart. - , ScanQuoted, , EndQuoted. - , FieldStart. , , . FieldStart, ( ). , , , ScanField. , .
|
|
2. CSV
, , . ( , . , , , EndQuoted, - , "".)
- , . 2.
2. CSV
procedure TDExtractFields(const S: string; aList: TStrings);
Type
TStates = (FieldStart, ScanField, ScanQuoted, EndQuoted, GotError);
Var
State: TStates;
Inx: integer;
Ch: AnsiChar;
CurField: string;
Begin
{ FieldStart}
Assert(aList <> nil, 'TDExtractFields: list is nil');
aList.Clear;
State:= FieldStart;
CurField:= '';
{ }
for Inx:= 1 to length(S) do begin
{ }
Ch:= S[Inx];
{ }
Case State of
FieldStart:
Begin
case Ch of
'"':
Begin
State:= ScanQuoted;
end;
',':
Begin
aList.Add('');
end;
Else
CurField:= Ch;
State:= ScanField;
end;
end;
ScanField:
Begin
if (Ch = ',') then begin
aList.Add(CurField);
CurField:= '';
State:= FieldStart;
End
Else
CurField:= CurField + Ch;
end;
ScanQuoted:
Begin
if (Ch = '"') then
State:= EndQuoted
Else
CurField:= CurField + Ch;
end;
EndQuoted:
Begin
if (Ch = ',') then begin
aList.Add(CurField);
CurField:= '';
State:= FieldStart;
End
Else
State:= GotError;
end;
GotError:
Begin
raise EtdStateException.Create(
FmtLoadStr(tdeStateBadCSV,
[UnitName, 'TDExtractFields']));
end;
end;
end;
{ ScanQuoted GotError }
if (State = ScanQuoted) or (State = GotError) then
raise EtdStateException.Create(
FmtLoadStr(tdeStateBadCSV,
[UnitName, 'TDExtractFields']));
{ , }
if (CurField <> '') then
aList.Add(CurField);
end;
. TDExtractFields , .