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

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


当前回答

如果你想重新发明轮子,下面的方法可能对你有用:

public static IEnumerable<string> SplitCSV(string line)
{
    var s = new StringBuilder();
    bool escaped = false, inQuotes = false;
    foreach (char c in line)
    {
        if (c == ',' && !inQuotes)
        {
            yield return s.ToString();
            s.Clear();
        }
        else if (c == '\\' && !escaped)
        {
            escaped = true;
        }
        else if (c == '"' && !escaped)
        {
            inQuotes = !inQuotes;
        }
        else
        {
            escaped = false;
            s.Append(c);
        }
    }
    yield return s.ToString();
}

其他回答

实际上,CSV格式有一个规范,RFC 4180以及如何处理逗号:

包含换行符(CRLF)、双引号和逗号的字段应该用双引号括起来。

http://tools.ietf.org/html/rfc4180

所以,要有值foo和bar,baz,你这样做:

foo,"bar,baz"

另一个需要考虑的重要需求(同样来自规范):

如果使用双引号括起字段,则使用双引号 在字段中出现时,必须在字段前面加上 另一个双引号。例如: “aaa级”、“b”“bb”、“ccc”

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

由于这是关于一般实践,让我们从经验法则开始:

不要使用CSV,而是使用带有库的XML来读写XML文件。 如果必须使用CSV。正确操作并使用免费库来解析和存储CSV文件。

为了证明1),大多数CSV解析器没有编码意识,所以如果你不处理US-ASCII,你是在自找麻烦。 例如,excel2002以本地编码存储CSV,而没有任何关于编码的说明。CSV标准没有被广泛采用:(。 另一方面,xml标准被很好地采用,它处理编码非常好。

为了证明2),几乎所有语言都有大量的csv解析器,所以即使解决方案看起来非常简单,也没有必要重新发明轮子。

举几个例子:

对于python使用构建CSV模块 为perl检查CPAN和文本::CSV 对于PHP,使用内置的fgetcsv/fputcsv函数 java检查SuperCVS库

实际上,如果你不打算在嵌入式设备上解析它,就没有必要手动实现它。

首先,让我们问问自己,“为什么我们觉得需要在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

感谢这篇文章中的其他人。

我使用这里的信息在JavaScript中创建了一个函数,该函数将为一个对象数组获取csv输出,该对象数组的属性值可能包含逗号。

like

rowsArray = [{obj1prop1: "foo", obj1prop2: "bar,baz"}, {obj2prop1: "qux", obj2prop2: "quux,corge,thud"}]

into

csvRowsArray = [{obj1prop1: "foo", obj1prop2: "\"bar,baz\""}, {...} ] 

要在csv中的值中使用逗号,值需要用双引号括起来。为了在json对象的值中有双引号,它们只需要转义,即,“\”,反斜杠双引号。这里的转义是通过在模板文本中添加子元素并包括必要的引号' "${row[key]}" '来实现的。引号在放入对象时被转义。

这是我的函数:

const calculateTheCSVExport = (props) => {
  if (props.rows === undefined) return;

  let jsonRowsArray = props.rows;
  // console.log(jsonRowsArray);

  let csvRowsArrayNoCommasInObjectValues = [];
  let csvCurrRowObject = {}

  jsonRowsArray.forEach(row => {
    Object.keys(row).forEach(key => {
      // console.log(key, row[key])
      if (row[key].indexOf(',') > -1) {
        csvCurrRowObject = {...csvCurrRowObject, [key]: `"${row[key]}"`} // enclose value in escaped double quotes in JSON in order to export commas to csv correctly. see more: https://stackoverflow.com/questions/769621/dealing-with-commas-in-a-csv-file
      } else {
        csvCurrRowObject = {...csvCurrRowObject, [key]: row[key]}
      }
    });

    csvRowsArrayNoCommasInObjectValues.push(csvCurrRowObject);
    csvCurrRowObject = {};
  })

  // console.log(csvRowsArrayNoCommasInObjectValues)
  return csvRowsArrayNoCommasInObjectValues;
}