我试图在Perl中逐行阅读以下CSV文件内容。
CSV文件内容:
A7777777.A777777777.XXX3604,XXX,3604,YES,9
B9694396.B216905785.YYY0018,YYY,0018,YES,13
C9694396.C216905785.ZZZ0028,ZZZ,0028,YES,16
我可以使用以下代码拆分行内容,也可以验证内容:
@column_fields1 = split(',', $_);
print $column_fields1[0],"\n";
我也在尝试在CSV文件的第一列中找到第二部分(即 A777777777 或 B216905785 < / strong>或 C216905785 )–使用以下代码用.
分隔的第一列,我无法获取。
相反,只打印了一行。
my ($v1, $v2, $v3) = split(".", $column_fields1[0]);
print $v2,"\n";
有人可以建议我如何拆分数组元素并获得上述值吗?
在我的功能上,我完全需要某个地方的第一列值,而只需要某个地方的第二个部分。
下面是我的代码:
use strict;
use warnings;
my $dailybillable_tab_section1_file = "./sql/demanding_01_T.csv";
open(FILE, $dailybillable_tab_section1_file) or die "Could not read from $dailybillable_tab_section1_file, program halting.";
my @column_fields1;
my @column_fields2;
while (<FILE>)
{
chomp;
@column_fields1 = split(',', $_);
print $column_fields1[0],"\n";
my ($v1, $v2, $v3) = split(".",$column_fields1[0]);
print $v2,"\n";
if($v2 ne 'A777777777')
{
…
…
…
}
else
{
…
…
…
}
}
close FILE;
答案 0 :(得分:2)
split
将正则表达式作为第一个参数。您可以向它传递一个字符串(如在代码中一样),但是字符串的内容将在运行时简单地解释为正则表达式。
对于,
(在正则表达式中没有特殊含义)而言,这不是问题,但它会与.
(与正则表达式中的任何(非换行符)字符匹配)中断。
您尝试解决split "\."
的问题失败,因为"\."
与"."
相同:反斜杠具有其正常的字符串转义含义,但是由于.
不是字符串中的特殊字符,转义它无效。您可以通过仅打印结果字符串来查看:
print "\.\n"; # outputs '.', same as print ".\n";
然后.
被解释为正则表达式,从而引起您所观察到的问题。
通常的解决方法是将正则表达式传递给split
:
split /\./, $string
现在,反斜杠被解释为正则表达式的一部分,从而强制.
从字面上进行匹配。
如果您真的想传递一个字符串进行分割(我不确定为什么要这么做),您也可以这样:
split "\\.", $string
第一个反斜杠转义第二个反斜杠,得到两个字符串(\.
),当将其解释为正则表达式时,其含义与/\./
相同。
答案 1 :(得分:1)
如果您查看split()
的文档,就会发现它提供了以下调用函数的方法:
分割/ PATTERN /,EXPR,LIMIT
分割/ PATTERN /,EXPR
分割/模式/
分割
在其中三个示例中,该函数的第一个参数为/PATTERN/
。也就是说,split()
期望得到一个正则表达式,该正则表达式定义输入字符串的分割方式。
认识到此参数是一个正则表达式,而不是字符串,这一点非常重要。不幸的是,Perl的解析器并没有坚持这一点。它允许您使用看起来像字符串的第一个参数(已完成)。但是,不管它看起来如何,它都不是字符串。这是一个正则表达式。
因此,您使用如下代码感到困惑:
split(".",$COLUMN_FIELDS1[0])
如果您使第一个参数看起来像正则表达式,那么您将更可能意识到第一个参数是正则表达式,因此,需要转义一个点以防止将其解释为元字符。
split(/\./, $COLUMN_FIELDS1[0])
更新:Perl程序员普遍认为,带有大写字母名称的变量是常量,并且不会更改其值。通过对标准变量使用大写字母的名称,您很可能会使下一个编辑您的代码的人(六个月后很可能成为您)感到困惑。