我正在查看我的分隔文件(例如CSV,tab分离等)解析选项,一般基于MS堆栈,特别是.net.我排除的唯一技术是SSIS,因为我已经知道它不能满足我的需求.
所以我的选择似乎是:
我有两个必须符合的标准.首先,给定以下文件,其中包含两个逻辑数据行(以及共五个物理行):
101, Bob, "Keeps his house ""clean"".
Needs to work on laundry."
102, Amy, "Brilliant.
Driven.
Diligent."
解析后的结果必须产生两个逻辑"行",每行包含三个字符串(或列).第三行/列字符串必须保留换行符!换句话说,由于"未闭合"文本限定符,解析器必须识别行何时"继续"到下一个物理行上.
第二个标准是每个文件的分隔符和文本限定符必须是可配置的.以下是两个字符串,取自不同的文件,我必须能够解析:
var first = @"""This"",""Is,A,Record"",""That """"Cannot"""", they say,"","""",,""be"",rightly,""parsed"",at all";
var second = @"~This~|~Is|A|Record~|~ThatCannot~|~be~|~parsed~|at all";
Run Code Online (Sandbox Code Playgroud)
正确解析字符串"first"将是:
'_'仅表示捕获了空白 - 我不希望出现文字下划线.
可以对要解析的平面文件做出一个重要的假设:每个文件将有固定数量的列.
现在深入了解技术方案.
正则表达式
首先,许多响应者评论说正则表达式"不是实现目标的最佳方式".但是,我确实找到了一位提供优秀CSV正则表达式的评论者:
var regex = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
var Regex.Split(first, regex).Dump();
Run Code Online (Sandbox Code Playgroud)
应用于字符串"first"的结果非常精彩:
如果清除报价会很好,但我可以轻松地将其作为后处理步骤来处理.否则,此方法可用于解析样本字符串"first"和"second",前提是相应地修改了正则表达式和管道符号.优秀!
但真正的问题与多线标准有关.在将正则表达式应用于字符串之前,我必须从文件中读取完整的逻辑"行".不幸的是,我不知道要读取多少物理行来完成逻辑行,除非我有一个正则表达式/状态机.
所以这成了"鸡与鸡蛋"的问题.我最好的选择是将整个文件作为一个巨大的字符串读入内存,让正则表达式排序多行(我没有检查上面的正则表达式是否可以处理).如果我有一个10 gig文件,这可能有点不稳定.
到下一个选项.
TextFieldParser
三行代码将使此选项的问题变得明显:
var reader = new Microsoft.VisualBasic.FileIO.TextFieldParser(stream);
reader.Delimiters = new string[] { @"|" };
reader.HasFieldsEnclosedInQuotes = true;
Run Code Online (Sandbox Code Playgroud)
Delimiters配置看起来不错.但是,"HasFieldsEnclosedInQuotes"是"游戏结束".令我震惊的是,分隔符是可任意配置的,但相比之下我除了引用之外没有其他限定符选项.请记住,我需要对文本限定符进行配置.所以,除非有人知道TextFieldParser配置技巧,否则这就是游戏结束.
OLEDB
一位同事告诉我这个选项有两个主要的缺点.首先,它对于大型(例如10Gig)文件具有可怕的性能.其次,我被告知,它会猜测输入数据的数据类型,而不是让你指定.不好.
救命
所以我想知道我弄错的事实(如果有的话),以及我错过的其他选项.也许有人知道陪审团使用任意分隔符的方法.也许OLEDB已经解决了所述的问题(或者从未有过它们?).
你说什么?
| 归档时间: |
|
| 查看次数: |
34718 次 |
| 最近记录: |