【发布时间】:2011-05-26 08:12:41
【问题描述】:
当给定一个逗号分隔值列表(如3, asdf, *#, 1212.3)时,我想提取这些值中的每一个,不包括逗号,所以我将有一个像[3, "asdf", "*#", 1212.3] 这样的值列表(不是像那样的文本表示,但作为“命中”的数组)。我该怎么做?
【问题讨论】:
-
用什么编程语言?
当给定一个逗号分隔值列表(如3, asdf, *#, 1212.3)时,我想提取这些值中的每一个,不包括逗号,所以我将有一个像[3, "asdf", "*#", 1212.3] 这样的值列表(不是像那样的文本表示,但作为“命中”的数组)。我该怎么做?
【问题讨论】:
我看到您使用的是 D 编程语言。这是CSV parser for D的链接。
【讨论】:
首先,如果您正在处理 CSV 文件,请不要使用正则表达式或您自己的解析器。基本上,当您认为事情很简单时,事实并非如此,Stop Rolling Your Own CSV Parser。
接下来,您说您想要一个数组 ([3, "asdf", "*#", 1212.3])。这看起来是混合类型,不能用静态语言完成。最终即使使用 std.variant 也是非常低效的。对于每个解析的值,您将拥有如下代码:
try {
auto data = to!double(parsedValue);
auto data2 = to!int(data);
if(data == data2)
returnThis = Variant(data2);
else
returnThis = Variant(data);
} catch(ConvException ce) { }
现在,如果您的数据确实由一些定义的字符集分隔,并且没有用新行分成记录,那么您可以使用 std.algorithm 中的 split(", ")。否则使用 CSV 解析器。如果您不想遵循标准包装解析器,那么数据就是您想要的。在您的示例中,您有空格,CSV 格式不会忽略这些空格,因此请在输出上调用 strip()。
在the article I linked 中提到,通常发生的情况是人们会以最简单的形式编写解析器,而不是处理更复杂的情况。因此,当您寻找 CSV 解析器时,您会发现许多无法解决的问题。编写您自己的解析器出现了,我说这很好,只需处理所有有效的 CSV 文件。
幸运的是,您不需要编写自己的代码,因为我最近创建了 CSV Parser for D。目前没有进行错误检查,我不知道报告问题的最佳方法,以便可以更正解析并继续。使用示例可在 unittest 块中找到。你也可以解析一个结构:
struct MyData {
int a;
string b;
string c;
double d
}
foreach(data; csv.csv!MyData(str)) // I think I'll need to change the module/function name
//...
【讨论】:
在perl 中,您可以执行以下操作:
@anArray = split(',', "A,B,C,D,E,F,G");
【讨论】:
"my,first,field","my,second,field","my,third,field" 在 CSV 中是完全合法的。
(?:,|\s+)?([^ ,]+) 应该可以。
它跳过逗号或空格,然后选择除逗号或空格以外的任何内容。修改口味。
【讨论】: