我正在使用
读取来自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
存储为:
\" 1,234,123.00 \",\" 2,345.00 \", 342.00 ,\" 12,345.00 \"
当我真正想要的是这个时候:
1234123.00, 2345.00, 342.00, 12345.00
我之前使用clipData.Split(new string[] { "," }, StringSllitOptions.None))
函数将我的CSV剪贴板数据转换为一系列单元格,但是当存在包含逗号的转义格式文本时,这会失败。
我问是否有人能想出将这个字符串拆分成一组单元格的方法,忽略在\"
位内转义的逗号,因为这是Excel选择转义包含逗号的单元格的方式。
简而言之,我如何转换包含此字符串的单个字符串:
\" 1,234,123.00 \",\" 2,345.00 \", 342.00 ,\" 12,345.00 \"
进入包含以下内容的字符串数组:
{ "1,234,123.00", "2,345.00", "342.00", "12,345.00" }
不会破坏我解析一个简单的逗号分隔字符串的能力。
***** ***编辑
在此处跟进问题(表述为DFA):Split a string based on each time a Deterministic Finite Automata reaches a final state?
答案 0 :(得分:3)
首先,我之前处理过Excel中的数据,您通常看到的是逗号分隔值,如果该值被视为字符串,则它将包含双引号(并且可以包含逗号和双引号)。如果它被认为是数字,则没有双引号。此外,如果数据包含双引号,则会用""
这样的双引号分隔。所以假设所有这些都是我过去处理过这个问题的方法
public static IEnumerable<string> SplitExcelRow(this string value)
{
value = value.Replace("\"\"", """);
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(""","\"");
currStartIndex = i + 1;
}
}
}
yield return value.Substring(currStartIndex, value.Length - currStartIndex)
.Trim()
.Replace("\"", "")
.Replace(""", "\"");
}
当然这假设进入的数据是有效的,所以如果你有类似"fo,o"b,ar","bar""foo"
这样的东西,这将无效。此外,如果您的数据包含"
,那么它将变为“可能或可能不合适的数据。”
答案 1 :(得分:1)
有很多方法可以做到这一点。一种不起眼的方法是:
现在你有了第一个想要的东西
答案 2 :(得分:1)
我同意Kyle关于你的字符串可能不一致。
而不是凯尔的第一步,你可以使用
string[] vals = Regex.Split(value, @"\s*\"",\s*");
答案 3 :(得分:0)
从您的输入示例中,我们可以看到有三个“不需要的”字符序列:
\"
\",
,\"
因此,将所有这些序列添加到Split
方法的输入数组中:
string[] result = clipData.Split(new[] { @",\""", @"\"",", @"\""" },
StringSplitOptions.None);
这将为您提供一个包含一些空元素的数组。如果这是一个问题,请使用StringSplitOptions.RemoveEmptyEntries
代替StringSplitOptions.None
:
string[] result = clipData.Split(new[] { @",\""", @"\"",", @"\""" },
StringSplitOptions.RemoveEmptyEntries);
答案 4 :(得分:0)
您可以尝试使用一点LINQ:
string excelData = "\\\" 1,234,123.00 \\\",\\\" 2,345.00 \\\", 342.00 ,\\\" 12,345.00 \\\"";
IEnumerable<string> cells = from x in excelData.Split(new string[] { "\\\"" }, StringSplitOptions.RemoveEmptyEntries)
let y = x.Trim(',').Trim()
where !string.IsNullOrWhiteSpace(y)
select y;
或者,如果您不喜欢这个建议,请尝试使用RegEx实现类似的模式。