我正在寻找关于如何处理正在创建的csv文件的建议,然后由我们的客户上传,并且可能在值中有逗号,如公司名称。

我们正在考虑的一些想法是:带引号的标识符(value "," values ","等等)或使用|代替逗号。最大的问题是我们必须让它变得简单,否则客户就不会这么做。


当前回答

如果您在*nix-系统上,可以访问sed,并且仅在您的CSV的特定字段中可以有一个或多个不需要的逗号,您可以使用以下一行程序,以便将它们包含在RFC4180 Section 2中:

sed -r 's/([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*)/\1"\2"\3/' inputfile

根据不需要的逗号可能在哪个字段中,您必须更改/扩展正则表达式的捕获组(以及替换)。 上面的示例将第四个字段(六个字段中的第四个字段)括在引号中。

结合使用——In -place选项,您可以将这些更改直接应用到文件。

为了“构建”正确的正则表达式,需要遵循一个简单的原则:

对于CSV中出现在不需要的逗号字段之前的每个字段,您可以编写一个[^,]*,并将它们放在一个捕获组中。 对于包含不需要的逗号的字段,请写入(.*)。 对于带不需要的逗号的字段后面的每个字段,都要写一个,。*并将它们放在一个捕获组中。

下面是根据特定字段的不同可能的正则表达式/替换的简短概述。如果没有给出,则替换为\1"\2"\3。

([^,]*)(,.*)                     #first field, regex
"\1"\2                           #first field, substitution

(.*,)([^,]*)                     #last field, regex
\1"\2"                           #last field, substitution


([^,]*,)(.*)(,.*,.*,.*)          #second field (out of five fields)
([^,]*,[^,]*,)(.*)(,.*)          #third field (out of four fields)
([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*) #fourth field (out of six fields)

如果您想用sed删除不需要的逗号,而不是用引号将它们括起来,请参考此答案。

其他回答

如果您在*nix-系统上,可以访问sed,并且仅在您的CSV的特定字段中可以有一个或多个不需要的逗号,您可以使用以下一行程序,以便将它们包含在RFC4180 Section 2中:

sed -r 's/([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*)/\1"\2"\3/' inputfile

根据不需要的逗号可能在哪个字段中,您必须更改/扩展正则表达式的捕获组(以及替换)。 上面的示例将第四个字段(六个字段中的第四个字段)括在引号中。

结合使用——In -place选项,您可以将这些更改直接应用到文件。

为了“构建”正确的正则表达式,需要遵循一个简单的原则:

对于CSV中出现在不需要的逗号字段之前的每个字段,您可以编写一个[^,]*,并将它们放在一个捕获组中。 对于包含不需要的逗号的字段,请写入(.*)。 对于带不需要的逗号的字段后面的每个字段,都要写一个,。*并将它们放在一个捕获组中。

下面是根据特定字段的不同可能的正则表达式/替换的简短概述。如果没有给出,则替换为\1"\2"\3。

([^,]*)(,.*)                     #first field, regex
"\1"\2                           #first field, substitution

(.*,)([^,]*)                     #last field, regex
\1"\2"                           #last field, substitution


([^,]*,)(.*)(,.*,.*,.*)          #second field (out of five fields)
([^,]*,[^,]*,)(.*)(,.*)          #third field (out of four fields)
([^,]*,[^,]*,[^,]*,)(.*)(,.*,.*) #fourth field (out of six fields)

如果您想用sed删除不需要的逗号,而不是用引号将它们括起来,请参考此答案。

在字符串周围加双引号。这就是Excel所做的。

阿拉伊莱,

将双引号转义为2 双引号。如。 “test1”、“foo”“酒吧”,“test2”

在欧洲,我们有这个问题必须早于这个问题。在欧洲,我们用逗号来表示小数点。请看下面的数字:

| American      | Europe        |
| ------------- | ------------- |
| 0.5           | 0,5           |
| 3.14159265359 | 3,14159265359 |
| 17.54         | 17,54         |
| 175,186.15    | 175.186,15    |

因此,CSV文件不能使用逗号分隔符。由于这个原因,欧洲的CSV文件由分号(;)分隔。

像微软Excel这样的程序可以读取带有分号的文件,也可以从分隔符切换到分号。您甚至可以使用制表符(\t)作为分隔符。请看来自Supper用户的回答。

使用制表符(\t)分隔字段。

首先,让我们问问自己,“为什么我们觉得需要在CSV文件中以不同的方式处理逗号?”

对我来说,答案是:“因为当我将数据导出到CSV文件时,字段中的逗号消失了,我的字段被分隔成多个字段,其中逗号出现在原始数据中。”(这是因为逗号是CSV字段分隔符。)

根据您的情况,分号也可以用作CSV字段分隔符。

根据我的要求,我可以使用一个字符,例如,单个低9引号,它看起来像一个逗号。

所以,下面是你在Go中如何做到这一点:

// Replace special CSV characters with single low-9 quotation mark
func Scrub(a interface{}) string {
    s := fmt.Sprint(a)
    s = strings.Replace(s, ",", "‚", -1)
    s = strings.Replace(s, ";", "‚", -1)
    return s
}

Replace函数中的第二个逗号字符是十进制8218。

请注意,如果您的客户端可能只有ascii文本阅读器,那么这个十进制8218字符看起来不会像逗号。如果这是您的情况,那么根据RFC 4128,我建议用逗号(或分号)和双引号包围字段:https://www.rfc-editor.org/rfc/rfc4180