【问题标题】:Extracting values from comma separated lists从逗号分隔的列表中提取值
【发布时间】:2011-05-26 08:12:41
【问题描述】:

当给定一个逗号分隔值列表(如3, asdf, *#, 1212.3)时,我想提取这些值中的每一个,不包括逗号,所以我将有一个像[3, "asdf", "*#", 1212.3] 这样的值列表(不是像那样的文本表示,但作为“命中”的数组)。我该怎么做?

【问题讨论】:

  • 用什么编程语言?

标签: regex csv extract d


【解决方案1】:

我看到您使用的是 D 编程语言。这是CSV parser for D的链接。

【讨论】:

  • 很抱歉没有给 cmets 带来那么多麻烦。但是单元测试部分应该给出很好的例子来说明它是如何使用的。这可能是一个更好的 URL:github.com/he-the-great/JPDLibs/tree/csv
  • @he_the_great:我已将链接更新为您建议的新链接。谢谢。
【解决方案2】:

首先,如果您正在处理 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
    //...

【讨论】:

    【解决方案3】:

    在perl 中,您可以执行以下操作:

    @anArray = split(',', "A,B,C,D,E,F,G");
    

    【讨论】:

    • 如果某些 CSV 字段有逗号怎么办?例如。 "my,first,field","my,second,field","my,third,field" 在 CSV 中是完全合法的。
    • 反正 OP 使用的是 D 编程语言。所以 perl 答案是不相关的。
    • @Asaph 对我的建议感到非常抱歉,我的帖子似乎就像对 D 语言的澄清一样。无论如何,如果字段中存在逗号,那么我认为任何 CSV 解析器都会有问题,除非每个字段都用引号括起来,在这种情况下,您需要在解析时计算引号。
    • @Bnjmn:CSV解析的规则很简单,解析器也很容易实现。我已经做到了。如果字段值包含以下任何内容,则必须用双引号括住字段:逗号、回车、换行符或双引号字符。在带引号的字符串中,双引号字符被另一个双引号字符转义。如果字段值具有前导或尾随空格,则应将其括在双引号中。用双引号括起来在所有其他时间都是可选的。就是这样!
    • 出于我的目的,逗号是非法输入(实际上它只是将值一分为二)。
    【解决方案4】:

    (?:,|\s+)?([^ ,]+) 应该可以。 它跳过逗号或空格,然后选择除逗号或空格以外的任何内容。修改口味。

    【讨论】:

    • 即使对于简单的 CSV 格式,这也太简单了。有关详细信息,请参阅@Bnjmn 中的 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多