Недавно я был информирован уважаемым пользователем SO, что TStringList
имеет разбиение ошибок, которые могут привести к сбою в обработке данных CSV. Я не был проинформирован о характере этих ошибок, и поиск в Интернете, включая Quality Central, не дал никаких результатов, поэтому я спрашиваю. Что такое расщепления TStringList?
Пожалуйста, заметьте, меня не интересуют необоснованные ответы на основе мнения.
Что я знаю:
Не так много... Одно из них: эти ошибки появляются редко с тестовыми данными, но не так редко в реальном мире.
Другое, как заявлено, предотвращает правильный анализ CSV. Думая, что трудно воспроизвести ошибки с тестовыми данными, я (возможно) обратился за помощью от тех, кто попытался использовать строковый список в качестве анализатора CSV в производственном коде.
Неприемлемые проблемы:
Я получил информацию по теме "Delphi-XE" с тегами, поэтому неудачный синтаксический анализ из-за "пробельного символа, который рассматривается как разделитель" , не применяется, Потому что введение свойства StrictDelimiter
с Delphi 2006 разрешило это. Я сам использую Delphi 2007.
Кроме того, поскольку список строк может содержать только строки, он отвечает только за разделение полей. Любая сложность преобразования, включающая значения полей (f.i. date, числа с плавающей запятой..), возникающие из-за различий в языковых курсах и т.д., Не имеет значения.
Основные правила:
Нет стандартной спецификации для CSV. Но есть основные правила, вытекающие из различных спецификаций.
Ниже показано, как обрабатывает TStringList. Строки правил и примеров из Wikipedia. Кронштейны ([
]
) накладываются вокруг строк, чтобы иметь возможность видеть передние или конечные пробелы (где это необходимо) с помощью тестового кода.
Пространства считаются частью поля и не должны игнорироваться.
Test string: [1997, Ford , E350] Items: [1997] [ Ford ] [ E350]
Поля со встроенными запятыми должны быть заключены в символы двойной кавычки.
Test string: [1997,Ford,E350,"Super, luxurious truck"] Items: [1997] [Ford] [E350] [Super, luxurious truck]
Поля со встроенными символами двойной кавычки должны быть заключены в символы двойной кавычки, и каждый из встроенных символов двойной кавычки должен быть представлен двумя символами двойной кавычки.
Test string: [1997,Ford,E350,"Super, ""luxurious"" truck"] Items: [1997] [Ford] [E350] [Super, "luxurious" truck]
Поля со встроенными разрывами строк должны быть заключены в символы двойной кавычки.
Test string: [1997,Ford,E350,"Go get one now they are going fast"] Items: [1997] [Ford] [E350] [Go get one now they are going fast]
В реализациях CSV, которые обрезают ведущие или конечные пробелы, поля с такими пространствами должны быть заключены в символы двойной кавычки.
Test string: [1997,Ford,E350," Super luxurious truck "] Items: [1997] [Ford] [E350] [ Super luxurious truck ]
Поля всегда могут быть заключены в символы двойной кавычки, независимо от того, нужно или нет.
Test string: ["1997","Ford","E350"] Items: [1997] [Ford] [E350]
Код тестирования:
var
SL: TStringList;
rule: string;
function GetItemsText: string;
var
i: Integer;
begin
for i := 0 to SL.Count - 1 do
Result := Result + '[' + SL[i] + '] ';
end;
procedure Test(TestStr: string);
begin
SL.DelimitedText := TestStr;
Writeln(rule + sLineBreak, 'Test string: [', TestStr + ']' + sLineBreak,
'Items: ' + GetItemsText + sLineBreak);
end;
begin
SL := TStringList.Create;
SL.Delimiter := ','; // default, but ";" is used with some locales
SL.QuoteChar := '"'; // default
SL.StrictDelimiter := True; // required: strings are separated *only* by Delimiter
rule := 'Spaces are considered part of a field and should not be ignored.';
Test('1997, Ford , E350');
rule := 'Fields with embedded commas must be enclosed within double-quote characters.';
Test('1997,Ford,E350,"Super, luxurious truck"');
rule := 'Fields with embedded double-quote characters must be enclosed within double-quote characters, and each of the embedded double-quote characters must be represented by a pair of double-quote characters.';
Test('1997,Ford,E350,"Super, ""luxurious"" truck"');
rule := 'Fields with embedded line breaks must be enclosed within double-quote characters.';
Test('1997,Ford,E350,"Go get one now'#10#13'they are going fast"');
rule := 'In CSV implementations that trim leading or trailing spaces, fields with such spaces must be enclosed within double-quote characters.';
Test('1997,Ford,E350," Super luxurious truck "');
rule := 'Fields may always be enclosed within double-quote characters, whether necessary or not.';
Test('"1997","Ford","E350"');
SL.Free;
end;
Если вы все прочитали, вопрос был:), что такое "TStringList расщепление ошибок?"