Ser*_*yuz 30 csv delphi tstringlist delphi-2007
最近我被一位声誉卓着的SO用户告知,它TStringList有分裂错误,导致它无法解析CSV数据.我没有被告知这些错误的性质,在互联网上搜索包括Quality Central没有产生任何结果,所以我问.什么是TStringList拆分错误?
请注意,我对没有根据意见的答案感兴趣.
我知道的:
并不多......其中一个就是,这些错误很少出现在测试数据中,但在现实世界中却很少见.
另一方面,如上所述,它们阻止了对CSV的正确解析.认为很难用测试数据重现错误,我(可能)寻求帮助,他们尝试在生产代码中使用字符串列表作为CSV解析器.
无关紧要的问题:
我获取了有关'Delphi-XE'标记问题的信息,因此由于"空格字符被视为分隔符" 功能而无法解析,因此不适用.因为StrictDelimiterDelphi 2006 引入的属性解决了这个问题.我,我自己,正在使用Delphi 2007.
此外,由于字符串列表只能包含字符串,因此它只负责拆分字段.涉及由区域差异等引起的字段值(fi日期,浮点数......)的任何转换难度都不在范围内.
基本规则:
CSV没有标准规范.但是从各种规范中可以推断出基本规则.
下面演示TStringList如何处理这些.规则和示例字符串来自维基百科.括号([ ])叠加在字符串周围,以便能够通过测试代码查看前导或尾随空格(相关).
空间被认为是一个领域的一部分,不应该被忽视.
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;
Run Code Online (Sandbox Code Playgroud)
如果您已经阅读了所有内容,问题是:),什么是"TStringList拆分错误?"
Cos*_*und 13
并不多......其中一个就是,这些错误很少出现在测试数据中,但在现实世界中却很少见.
所需要的只是一个案例.测试数据不是随机数据,一个用户有一个失败案例应该提交数据并且我们有一个测试用例.如果没人能提供测试数据,可能没有错误/失败?
CSV没有标准规范.
那个确定有助于混乱.没有标准规范,你如何证明出错?如果这是出于自己的直觉,你可能会遇到各种各样的麻烦.这里有一些来自我自己与政府发行的软件的快乐互动; 我的应用程序应该以CSV格式导出数据,政府应用程序应该导入它.这里是什么让我们陷入一个很大的麻烦几年连续:
Field,"",Field是无效的,应该是Field,,Field.有很多乐趣向我的客户解释gov应用程序将验证规则从一周更改为下一周......0,然后强制要求不包括0.也就是说,有一次Field,0,Field是有效的,接下来Field,,Field是唯一有效的方式......这是另一个测试案例,其中(我的)直觉失败了:
1997年,福特,E350,"超级豪华卡车"
请注意之间的空间,,并"Super和随后的很幸运逗号"Super.TStrings如果它紧跟在分隔符之后,那么所使用的解析器只能看到引号char .该字符串被解析为:
[1997]
[ Ford]
[ E350]
[ "Super]
[ luxurious truck"]
Run Code Online (Sandbox Code Playgroud)
直觉我期望:
[1997]
[ Ford]
[ E350]
[Super luxurious truck]
Run Code Online (Sandbox Code Playgroud)
但是猜猜看,Excel的做法与Delphi的做法相同......
TStrings.CommaText相当不错并且实现得很好,至少我看过的Delphi 2010版本是非常有效的(避免多个字符串分配,使用a PChar来"解析"解析后的字符串)并且与Excel的解析器的工作方式大致相同.TStrings.当它确实发生时,它可能不是TString错!