2

我有一个 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

因此,在逗号上拆分字符串,但忽略引号内的逗号。目前我正在使用以下正则表达式:

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

但是,这给了我以下结果:

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

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

4

4 回答 4

1

通常在 CSV 解析方面,人们使用非常适合他们用来编写应用程序的编程语言的特定库。

无论如何,如果您要使用正则表达式进行非常松散(!)的解析,您可以尝试使用以下内容:

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

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

[编辑]

我再次检查了您的问题,并注意到您还想包含未引用的字段……好吧,在这种情况下,我的表达将根本不起作用。不管怎样,听着……如果你认真思考你的问题,你会发现这是很难在没有歧义的情况下解决的。因为您需要固定规则,并且如果您允许引用和不引用字段,解析器将很难找出合法的逗号作为分隔符/引用。

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

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

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

于 2012-08-03T13:53:14.060 回答
0

This regex is based of the fact you have 1 digit before and after your 'value'

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

You can test it out on RegexStorm

于 2012-08-03T14:01:01.777 回答
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; 
    }

感谢大家的帮助。

于 2012-08-03T14:35:49.527 回答
0
foreach(var m in Regex.Matches(s,"(('.*?')|[0-9])"))
于 2012-08-03T18:30:19.253 回答