【问题标题】:Simple perl split() and Regular Expression question [duplicate]简单的 perl split() 和正则表达式问题 [重复]
【发布时间】:2011-09-20 00:29:48
【问题描述】:

可能重复:
How can I parse quoted CSV in Perl with a regex?

我正在尝试获取一个 CSV 文件并将每一行导入一个数组(其中每个元素代表一列)。 CSV文件的格式很简单:

item1,item2,item3
nextrowitem1,item2,item3
"items,with,commas","are,in,quotes"

我使用以下方法导入了 CSV 文件:

open(FILE, "test.csv");
@lines = <FILE>;

然后我使用:

foreach(@lines){
    @items = split(/regular expression/);
    /*Do stuff with @items array*/
}

(请注意,您不需要使用split(/regular expression, $string);,因为如果没有提供字符串,split() 会假定为$_

在我使用 CSV 文件测试文件之前,其中没有任何项目包含逗号和 split(/,/) 的简单正则表达式。这工作得很好,所以在这个正则表达式之后,文件、读取文件或我的循环没有任何问题。但是,当我点击包含逗号的项目时,它们会被这样划分,这是可以理解的:

1 => "items
2 => with
3 => commas"
4 => "are
5 => in
6 => quotes"

而不是想要的:

1 => items,with,commas
2 => are,in,quotes

谁能帮我开发一个正则表达式来正确拆分这个数组?基本上如果项目以引号(")开头,则需要等到"," 才能拆分。如果item不以引号开头,则需要等到,才能拆分。

【问题讨论】:

  • 感谢您链接到那个 =) 绝对是重复的 - 事实上,他的问题比我的更详细。我现在将研究 CPAN,看看我是否可以使用它。

标签: regex arrays perl split


【解决方案1】:

尝试阅读Text::CSV 作为已经这样做的可能选项。将 CSV 解析为正则表达式的问题在于,您必须查找 ","(您已指出)以及 , 分隔符之类的内容。

【讨论】:

  • 我同意。您不能使用正则表达式进行 CVS 拆分,因为逗号和引号可以在 CVS 字段中。唯一真正的方法是在循环中一点一点地分解行。 Text::CVS 为您创造奇迹。
  • @David、CVSCSV 非常不同。
  • 是的,我知道。不幸的是,我有阅读障碍,并且正在处理一个使用 CVS 的项目。混乱是必然发生的。我的意思是“CSV”。
【解决方案2】:

只需改用Text::CSV_XS...

【讨论】:

  • 或者使用Text::CSV,如果可以的话,它使用 Text::CSV_XS 来提高速度,但如果你没有 C 编译器,它也有一个纯 Perl 实现。
【解决方案3】:

请查看我的post that solves this problem 了解更多详情。

^(?:(?:"((?:""|[^"])+)"|([^,]*))(?:$|,))+$ 将匹配整行,然后您可以使用匹配的捕获来获取数据(不带引号)。

【讨论】:

  • 表达式以问号开头是什么意思?我知道^ab?会匹配aab,但是^(?:....有什么意义呢?我从没见过开头的问号...
  • 这是 CSV 模块的工作,正如其他答案所建议的那样,不是正则表达式
  • (?:expression) 表示非捕获组。这可以防止正则表达式引擎跟踪与表达式的该部分匹配的字符串部分。在此处查看 $1、$2、$3 等:regular-expressions.info/perl.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 1970-01-01
  • 2011-05-13
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多