使用RegEx读取CSV文件

时间:2012-08-03 13:44:19

标签: c# regex csv

我有一个CSV文件,其中包含以下类型的数据:

0,'VT,C',0,
0,'C,VT',0,
0,'VT,H',0,

我想要以下输出

0
VT,C
0
0
C,VT
0
0
VT,H
0

因此,在逗号上分割字符串,但忽略引号内的逗号。目前我正在使用以下RegEx:

("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)"

然而,这给了我以下结果:

0
VT
C
0
0
C
VT
0
0
VT
H
0

这表明RegEx没有正确读取引号。任何人都可以建议一些可能有帮助的改动吗?

4 个答案:

答案 0 :(得分:1)

通常,当涉及到CSV解析时,人们会使用特定的库,这些库非常适合他们用来编写应用程序的编程语言。

无论如何,如果你打算使用正则表达式进行一个非常宽松的(!)解析,你可以尝试使用这样的东西:

'(?<value>[^']*?)'

它将匹配单引号之间的任何内容,并假设csv文件格式正确,它将不会错过字段。当然它不接受嵌入式引号,但它很容易完成工作。这就是我在需要快速完成工作时所使用的。请不要认为它是您问题的完整解决方案......当需求与您描述的一致并且输入结构良好时,它只适用于特殊条件。

[编辑]

我再次检查你的问题,并注意到你想要包括非引用的字段......好吧,在这种情况下我的表达根本不起作用。无论如何听......如果你认真思考你的问题,你会发现这是很难解决的问题。因为你需要固定的规则,并且如果你允许引用而不是引用的字段,解析器将很难将合法逗号计算为分隔符/引用。

建模这种解决方案的另一个表达方式可能是:

('[^']+'|[^,]+),?

它将匹配引用/未引用的字段......无论如何,我不确定是否需要假设csv必须遵守严格的条件。据我所知,这比分裂策略更安全......你只需要收集所有匹配并在目标字符串上打印matched_value + \r\n

答案 1 :(得分:0)

此正则表达式基于'值'之前和之后 1 数字的事实

Regex.Replace(input, @"(?:(?<=\d),|,(?=\d))", "\n");

您可以在RegexStorm

上测试一下

答案 2 :(得分:0)

我已设法根据需要获取以下方法来读取文件:

public List<string> SplitCSV(string input, List<string> line)
    {

        Regex csvSplit = new Regex("(([^,^\'])*(\'.*\')*([^,^\'])*)(,|$)", RegexOptions.Compiled);

        foreach (Match match in csvSplit.Matches(input))
        {
            line.Add(match.Value.TrimStart(','));
        }
        return line; 
    }

感谢大家的帮助。

答案 3 :(得分:0)

foreach(var m in Regex.Matches(s,"(('.*?')|[0-9])"))