我认为这将是微不足道的,但我不能让这个工作.
假设CSV文件中有一行:
"Barack Obama", 48, "President", "1600 Penn Ave, Washington DC"
string[] tokens = line.split(',')
我期待这个:
"Barack Obama"
48
"President"
"1600 Penn Ave, Washington DC"
Run Code Online (Sandbox Code Playgroud)
但最后一个标记
'Washington DC'不是
"1600 Penn Ave, Washington DC".
是否有一种简单的方法可以让split函数忽略引号内的逗号?
我无法控制CSV文件但它没有发送给我.客户A将使用该应用程序读取外部个人提供的文件.
Dam*_*isa 14
您可能必须编写自己的拆分功能.
"字符时,切换一个布尔值这是一个例子:
public static class StringExtensions
{
public static string[] SplitQuoted(this string input, char separator, char quotechar)
{
List<string> tokens = new List<string>();
StringBuilder sb = new StringBuilder();
bool escaped = false;
foreach (char c in input)
{
if (c.Equals(separator) && !escaped)
{
// we have a token
tokens.Add(sb.ToString().Trim());
sb.Clear();
}
else if (c.Equals(separator) && escaped)
{
// ignore but add to string
sb.Append(c);
}
else if (c.Equals(quotechar))
{
escaped = !escaped;
sb.Append(c);
}
else
{
sb.Append(c);
}
}
tokens.Add(sb.ToString().Trim());
return tokens.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
然后打电话:
string[] tokens = line.SplitQuoted(',','\"');
Run Code Online (Sandbox Code Playgroud)
对我的代码和Dan Tao的代码进行基准测试的结果如下.如果有人想要,我很乐意为任何其他解决方案做基准测试吗?
码:
string input = "\"Barak Obama\", 48, \"President\", \"1600 Penn Ave, Washington DC\""; // Console.ReadLine()
string[] tokens = null;
// run tests
DateTime start = DateTime.Now;
for (int i = 0; i < 1000000; i++)
tokens = input.SplitWithQualifier(',', '\"', false);
Console.WriteLine("1,000,000 x SplitWithQualifier = {0}ms", DateTime.Now.Subtract(start).TotalMilliseconds);
start = DateTime.Now;
for (int i = 0; i<1000000;i++)
tokens = input.SplitQuoted(',', '\"');
Console.WriteLine("1,000,000 x SplitQuoted = {0}ms", DateTime.Now.Subtract(start).TotalMilliseconds);
Run Code Online (Sandbox Code Playgroud)
输出:
1,000,000 x SplitWithQualifier = 8156.25ms
1,000,000 x SplitQuoted = 2406.25ms
Run Code Online (Sandbox Code Playgroud)
Dan*_*Tao 11
我有一个SplitWithQualifier扩展方法,我在这里和那里使用,利用Regex.
我没有声明这段代码的健壮性,但它对我来说已经有一段时间了.
// mangled code horribly to fit without scrolling
public static class CsvSplitter
{
public static string[] SplitWithQualifier(this string text,
char delimiter,
char qualifier,
bool stripQualifierFromResult)
{
string pattern = string.Format(
@"{0}(?=(?:[^{1}]*{1}[^{1}]*{1})*(?![^{1}]*{1}))",
Regex.Escape(delimiter.ToString()),
Regex.Escape(qualifier.ToString())
);
string[] split = Regex.Split(text, pattern);
if (stripQualifierFromResult)
return split.Select(s => s.Trim().Trim(qualifier)).ToArray();
else
return split;
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
string csv = "\"Barak Obama\", 48, \"President\", \"1600 Penn Ave, Washington DC\"";
string[] values = csv.SplitWithQualifier(',', '\"', true);
foreach (string value in values)
Console.WriteLine(value);
Run Code Online (Sandbox Code Playgroud)
输出:
Barak Obama
48
President
1600 Penn Ave, Washington DC
Run Code Online (Sandbox Code Playgroud)
我从大局看到你实际上是在尝试解析CSV输入.因此,我建议您使用CSV解析器来执行此类操作,而不是建议如何正确地拆分字符串.
我建议的是可从此CodeProject页面获取的库(可用源代码):http://www.codeproject.com/KB/database/CsvReader.aspx
我亲自使用它并喜欢它.它是一个.NET本机代码,比使用OLEDB快得多(它也可以为你做CSV解析,但相信我,它很慢).
| 归档时间: |
|
| 查看次数: |
5773 次 |
| 最近记录: |