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

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


当前回答

我发现的最简单的解决方案是LibreOffice使用的:

替换所有“by”字面值 在字符串周围加上双引号

你也可以使用Excel使用的:

替换所有字面的" by " 在字符串周围加上双引号

注意,其他人建议只执行上面的第2步,但这对于“后面跟着一个,”的行不起作用,就像在CSV中,你想要有一个字符串hello”,world的单列,因为CSV会这样读:

"hello",world"

它被解释为有两列的行:hello和world"

其他回答

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

| 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用户的回答。

这里有一个简单的变通方法:

您可以使用希腊小写数字符号(U+0375)

看上去就像这样

使用这种方法也可以节省很多资源…

您可以在字段周围加上双引号。我不喜欢这种方法,因为它增加了另一个特殊字符(双引号)。只需定义一个转义字符(通常是反斜杠),并在需要转义的地方使用它:

data,more data,more data\, even,yet more

您不必尝试匹配引号,而且需要解析的异常也更少。这也简化了您的代码。

    public static IEnumerable<string> LineSplitter(this string line, char 
         separator, char skip = '"')
    {
        var fieldStart = 0;
        for (var i = 0; i < line.Length; i++)
        {
            if (line[i] == separator)
            {
                yield return line.Substring(fieldStart, i - fieldStart);
                fieldStart = i + 1;
            }
            else if (i == line.Length - 1)
            {
                yield return line.Substring(fieldStart, i - fieldStart + 1);
                fieldStart = i + 1;
            }

            if (line[i] == '"')
                for (i++; i < line.Length && line[i] != skip; i++) { }
        }

        if (line[line.Length - 1] == separator)
        {
            yield return string.Empty;
        }
    }

我发现的最简单的解决方案是LibreOffice使用的:

替换所有“by”字面值 在字符串周围加上双引号

你也可以使用Excel使用的:

替换所有字面的" by " 在字符串周围加上双引号

注意,其他人建议只执行上面的第2步,但这对于“后面跟着一个,”的行不起作用,就像在CSV中,你想要有一个字符串hello”,world的单列,因为CSV会这样读:

"hello",world"

它被解释为有两列的行:hello和world"