【发布时间】:2015-07-04 04:01:57
【问题描述】:
有一个名为file.csv 的csv 文件,如下所示:(这只是一个示例)
"Name","Alias","Phone","email","address"
"rob","rob","534235","rob@example.com","US,UK"
"nik","nik","976784","nik@example.com,nik@foram.org","UK"
"picy","pic","327654,823747","pic@example.com","US"
在这个文件中有 5 个标题,但少数标题的值更多。任何标题都可以有任意数量的值意味着超过 2 或 3。
我试图得到这样的输出:
Name Nickname Phone email address
rob rob 534235 rob@example.com US,UK
nik nik 976784 nik@example.com,nik@foram.org UK
picy pic 327654,823747 pic@example.com US
或任何特定列,但该列的数据将如上所示。
我知道split在spliting中的功能和限制:
while (<$fh>)
{
my @data = split /,/, $_, 5;
}
但这在这里不起作用。
我怎样才能做到这一点?有什么想法吗?
【问题讨论】:
-
Split 不够聪明,无法在这里做你想做的事。例如,您至少需要一个简单的解析器来确定一个字段是电话还是电子邮件。首先,您需要能够定义语法并确定值是哪种类型的字段 - 例如,看起来 123455 将是电话号码 - 因此正则表达式 \d{6} 将仅匹配电话号码。您还可以为电子邮件地址定义一个正则表达式,但名称/昵称的区别会更难。见some parsers on cpan
-
从 CPAN 下载 Text::CSV 或 Text::CSV_XS 并使用它。
-
@SinanÜnür:那么它不是 CSV 文件。 CPAN 背后的理念是其他人已经编写、调试并保存了他们的工作供您使用。不使用 CPAN 的模块意味着您正在重新发明轮子,这既昂贵又容易出错。
-
我投票决定将此问题作为离题结束,因为 OP 不断更改数据,从而使提议的解决方案无效。
-
@SinanÜnür:这就是我的观点:验证和拒绝输入。 “问题”往往不是问题而是无效输入。