除非分隔符被转义,否则使用分隔符拆分

Ala*_*ain 6 c# string excel clipboard

我正在阅读来自excel的剪贴板数据

var stream = (System.IO.Stream) ( Forms.Clipboard.GetDataObject() ).GetData( Forms.DataFormats.CommaSeparatedValue );,

但不幸的是,excel正在传递单元格文本而不是单元格值.当单元格使用特殊格式(例如千位分隔符)时,列中的一系列单元格的剪贴板数据如下所示:

 1,234,123.00    2,345.00    342.00      12,345.00
Run Code Online (Sandbox Code Playgroud)

存储如下:

\" 1,234,123.00 \",\" 2,345.00 \", 342.00 ,\" 12,345.00 \"
Run Code Online (Sandbox Code Playgroud)

当我真正想要的是这个:

 1234123.00, 2345.00, 342.00, 12345.00
Run Code Online (Sandbox Code Playgroud)

我以前使用该clipData.Split(new string[] { "," }, StringSllitOptions.None))函数将我的CSV剪贴板数据转换为一系列单元格,但是当存在包含逗号的转义格式化文本时,这会失败.


我问是否有人能想出一种方法将这个字符串拆分成一组单元格,忽略\"在位内转义的逗号,因为这是Excel选择转义包含逗号的单元格的方式.

简而言之,我如何转换包含此字符串的单个字符串:

\" 1,234,123.00 \",\" 2,345.00 \", 342.00 ,\" 12,345.00 \"
Run Code Online (Sandbox Code Playgroud)

到包含这个的字符串数组:

{ "1,234,123.00", "2,345.00", "342.00", "12,345.00" }
Run Code Online (Sandbox Code Playgroud)

不破坏我解析一个简单的逗号分隔字符串的能力.

*****编辑***

后续问题(表述为DFA):根据确定性有限自动机每次达到最终状态时拆分字符串?

juh*_*arr 4

首先,我之前处理过 Excel 中的数据,您通常看到的是逗号分隔的值,如果该值被视为字符串,它将带有双引号(并且可以包含逗号和双引号)。如果它被认为是数字,那么就没有双引号。此外,如果数据包含双引号,则将用双引号分隔,例如"". 所以假设这一切都是我过去处理这个问题的方式

public static IEnumerable<string> SplitExcelRow(this string value)
{
    value = value.Replace("\"\"", "&quot;");
    bool quoted = false;
    int currStartIndex = 0;
    for (int i = 0; i < value.Length; i++)
    {
        char currChar = value[i];
        if (currChar == '"')
        {
            quoted = !quoted;       
        }
        else if (currChar == ',')
        {
            if (!quoted)
            {
                yield return value.Substring(currStartIndex, i - currStartIndex)
                    .Trim()
                    .Replace("\"","")
                    .Replace("&quot;","\"");
                currStartIndex = i + 1;
            }
        }
    }
    yield return value.Substring(currStartIndex, value.Length - currStartIndex)
        .Trim()
        .Replace("\"", "")
        .Replace("&quot;", "\"");
}
Run Code Online (Sandbox Code Playgroud)

当然,这假设传入的数据是有效的,所以如果你有这样的东西"fo,o"b,ar","bar""foo"就行不通。此外,如果您的数据包含&quot;,那么它将变成“”,这可能是也可能不是所需的。