当数据中包含逗号时,如何将字符串按逗号拆分

5

我有一个CSV文件(这个文件不是我设计的,我现在也无法更改它,将来也不可能更改),其中包含以下行:

"姓,名",是的,不,一些字符串,任何东西,等等

正如你在这里看到的那样,第一个,不是我想要拆分字符串的逗号。请注意,这个特定的逗号被引号括起来。

因为这个原因,显然简单的string.split(',')方法行不通,因为它会给我一个长度为7的数组,而不是6。

有没有办法解决这个问题?我想使用正则表达式来拆分字符串,但我在正则表达式方面不够熟练,无法想出一个只在不被引号括起来的逗号处拆分的模式。

我可以想到丑陋、hacky的方法来逐个字符地读取每个字符串,但这必须是最后的手段,因为我相信肯定有更好的方法来解决这个问题!


这看起来像是来自Excel的.csv文件。总是很有趣。更有趣的是当数据包含引号和逗号时... - Jeff B
这实际上不是来自Excel,但是没错,很有趣! :) 它来自网络上的一个位置,我的程序读取文件并尝试解析它。 - AndrewC
1
逐个字符读取并不一定是一种丑陋的技巧。我建议你找一个C#的CSV解析器,因为我相信这样的工具已经存在了。 - Brian Donovan
作为一个丑陋的 hack 解决方案,你可以始终读取一个元素的第一个字符,如果它是引号,那么就将计数器加1,并将下一个索引值添加到前一个索引值中并继续。 - asawyer
+1 @Brian Donovan。如果代码不能正常工作,那么它的优雅也毫无意义。另外,如果值包含 " 字符会发生什么情况 - 它们会被加倍还是转义? - AakashM
@AakashM,如果值包含“`”字符,我不太确定会发生什么情况,从我在这个文件中看到的情况来看,这种情况并不会出现。 - AndrewC
3个回答

5

您引用了一个.NET 4.5的Visual Basic类,但这是一个C#问题的帖子。 - aggaton
2
@aggaton 只因类型在 Microsoft.VisualBasic 命名空间中,并不意味着它不能从 C# 中使用。TextFileParser 在 C# 中运行良好,它是核心框架的一部分 - 没有理由避免使用它。 - Reed Copsey
@ReedCopsey,应该是TextFieldParser,而不是TextFileParser。你成功地链接到了正确的东西,但一直写错了。 - Nyerguds
请注意,如果所有字段都用引号括起来,则应该设置HasFieldsEnclosedInQuotes。当我解析仅包含引号或逗号的字段被引号包围的 MS Excel 导出文件时,我将选项关闭,它完美地工作了。 - Nyerguds

2
我建议使用CSV解析库-有些情况你可能没有考虑到(例如,换行符作为引用字段的一部分)。
VisualBasic命名空间有一个很好的库可以帮助解析,叫做TextFieldParser。TextFieldParser

1
C#开发人员不必担心VisualBasic命名空间。在现实中没有任何意义,不会添加任何不在计算机上的依赖项等。 - user1228
漂亮,正如@Will所说,在C#中使用时非常好用。为什么微软要把这样的工具藏在如此奇怪的地方呢? - Nyerguds

1

我知道这里有很多人认为不应该使用逐个字符比较,并且会强烈反对我,但我并不认为像Microsoft这样的公司不是唯一应该做这种编程的公司。

毕竟,Split做字符比较,那么当你调用现有代码时,它为什么会更不好看呢?

无论如何,我的方法是编写自己的代码。 我已经在http://www.blackbeltcoder.com/Articles/files/reading-and-writing-csv-files-in-c上发布了代码。


谢谢Jonathan。我有点困惑如何使用你的代码,不确定为什么需要向ReadRow()传递参数? - AndrewC
运行得非常完美!谢谢Jonathan。 - AndrewC
很高兴听到这个消息。大多数文章都包含一个演示项目,但不是那个。谢谢你告诉我可能并不明显该方法应该如何调用。我会考虑更新它。 - Jonathan Wood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接