分析CSV:边缘案例



免责声明:我实际上不是在解析CSV,而是类似CSV的格式;我对使用预制图书馆不感兴趣。

解析以下两行的正确方法是什么?:

a,b"c"d,e
a,"bc"d,e

即,(a)在一个值的中间有引号,(b)在开始有引号,但在下一个值之前没有结束引号。

我不知道我应该如何处理这些情况(这将是最直观的)。


我的想法是,(a)应该解析为ab"c"de(中留有引号),(b)应该以相同的方式解析,a"bc"de。但让我介绍第三种情况,a,"b,c"d,e——我们是否在"b"one_answers"c"之间的第二个逗号上分开?

如果您想与Excel:保持一致,下面是您将如何解析它

输入:

a,b"c"d,e
a,"bc"d,e
a,"b,c"d,e

解析(JSON):

[
  ["a", "b"c"d", "e"],
  ["a", "bcd", "e"],
  ["a","b,cd", "e"]
]

解析逻辑为:

  • 如果行的第一个字符,或紧接在逗号之后的字符,是dbl引号,则:
    • 把它后面的一切都当作";引用";直到到达结束引号(当然,将连续两个引号视为转义的dbl引号)。从单元格值中删除左引号和右引号
    • 在";结束引号";已达到,请将单元格值中结束引号后的任何内容作为文字值,直到达到逗号或换行符为止
  • 否则,将逗号后面的所有内容都视为文字值,直到到达逗号或换行符为止

请注意,这意味着,如果在分隔逗号的单元格后面有一个空格,后面跟着一个dbl引号,则会得到与逗号后面没有空格(后面跟着dbl引号)不同的结果

这里是我的方法(C#)将csv吐到html表的一部分,它有这样的逗号解析:

string[] cells = line.Split(','); // empty cells needed as well
bool noComma = true;
for (int i = 0; i < cells.Length; i++)
{
    string cellI = cells[i];
    int numberOfDoubleQuote = cellI.Count(f => f == '"');
    // == 0 means comma in between quotes
    if (numberOfDoubleQuote == 1)
    {
        noComma = !noComma;
        if (!noComma)
            sLine += "<td>" + cellI;
        else
            sLine += "," + cellI + "</td>";
    }
    else
    {
        if (noComma)
            sLine += "<td>" + cellI + "</td>";
        else
            sLine += "," + cellI;
    }
}

最新更新