delphi – TStringList分裂错误
最近我被一个有信誉的SO用户通知,TStringList有分裂错误,这将导致它无法解析CSV数据。我没有被告知这些错误的性质,在互联网上包括
Quality Central的搜索没有产生任何结果,所以我问。什么是TStringList分解错误?
请注意,我对基于意见的答案不感兴趣。 我知道的: 没有多少…一个是,这些错误很少显示测试数据,但在现实世界中不那么少。 另一个是,如所述,它们阻止正确解析CSV。认为很难用测试数据重现错误,我(可能)寻求帮助,谁已经尝试使用字符串列表作为生产代码中的CSV解析器。 不相关问题: 我获得了关于“Delphi-XE”标记问题的信息,因此由于“空格字符被视为分隔符”feature而导致的解析失败不适用。因为引入的 此外,由于字符串列表只能保存字符串,它只负责拆分字段。涉及由于语言环境差异等引起的字段值(f.i.日期,浮点数字…)的任何转换难度不在范围内。 基本规则: CSV没有标准规范。但有从various specifications推断的基本规则。 下面是TStringList如何处理这些的演示。规则和示例字符串来自Wikipedia.括号([])叠加在字符串周围,以便能够通过测试代码查看前导或尾随空格(如果相关)。 空格被视为字段的一部分,不应被忽略。 Test string: [1997,Ford,E350] Items: [1997] [ Ford ] [ E350] 带有内置逗号的字段必须用双引号字符括起来。 Test string: [1997,E350,"Super,luxurious truck"] Items: [1997] [Ford] [E350] [Super,luxurious truck] 具有嵌入的双引号字符的字段必须包含在双引号字符中,每个嵌入的双引号字符必须由一对双引号字符表示。 Test string: [1997,""luxurious"" truck"] Items: [1997] [Ford] [E350] [Super,"luxurious" truck] 具有嵌入换行符的字段必须括在双引号字符中。 Test string: [1997,"Go get one now they are going fast"] Items: [1997] [Ford] [E350] [Go get one now they are going fast] 在修改前导或尾随空格的CSV实施中,具有此类空格的字段必须括在双引号字符中。 Test string: [1997," 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,E350'); rule := 'Fields with embedded commas must be enclosed within double-quote characters.'; Test('1997,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,""luxurious"" truck"'); rule := 'Fields with embedded line breaks must be enclosed within double-quote characters.'; Test('1997,"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," Super luxurious truck "'); rule := 'Fields may always be enclosed within double-quote characters,whether necessary or not.'; Test('"1997","E350"'); SL.Free; end; 如果你已经读过这一切,问题是:),什么是“TStringList分裂错误? 解决方法
它只需一个案例。测试数据不是随机数据,一个用户有一个失败的情况应该提交数据和voilà,我们有一个测试用例。如果没有人能提供测试数据,也许没有错误/失败?
那一个肯定有助于混乱。没有标准规范,你如何证明什么是错的?如果这是由自己的直觉,你可能会遇到各种各样的麻烦。这里有一些从我自己与政府发布的软件的快乐互动;我的应用程序应该导出CSV格式的数据,政府的应用程序应该导入它。这是什么让我们连续几年的很多麻烦: >如何表示空数据?由于没有CSV标准,一年我的友好的政府决定任何事情,包括没有(两个连续的逗号)。接下来他们决定只有连续的逗号就OK了,也就是Field,“”,字段无效,应该是Field,Field。有很多乐趣向我的客户解释,gov应用程序更改验证规则从一周到下一个… 这里是另一个测试用例(我的)直觉失败:
请注意之间的空格,以及“超级,和随后的很幸运的逗号”超级。 TStrings使用的解析器只能看到quote char,如果它紧跟在分隔符之后。该字符串解析为: [1997] [ Ford] [ E350] [ "Super] [ luxurious truck"] 直觉我会期望: [1997] [ Ford] [ E350] [Super luxurious truck] 但猜猜什么,Excel它是同样的方式Delphi做它… 结论 > TStrings.CommaText是相当不错,很好的实现,至少Delphi 2010版本我看看是相当有效(避免多个字符串分配,使用PChar“走”解析字符串)和工作方式与Excel的解析器相同。>在现实世界中,您需要与使用其他库(或根本没有库)编写的其他软件交换数据,其中人们可能会错过解释CSV的一些(缺少的)规则。你必须适应,它可能不是一个正确或错误的情况,但是一个“我的客户需要导入这个垃圾”的情况。如果发生这种情况,你必须编写自己的解析器,一个适应你要处理的第三方应用程序的要求。在这之前,你可以安全地使用TStrings。当它发生时,它可能不是TString的错! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |