【问题标题】:Split array element delimited with '.'拆分以“.”分隔的数组元素
【发布时间】:2019-06-03 12:43:53
【问题描述】:

我正在尝试在 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 文件的第一列中找到第二部分(即 A777777777B216905785C216905785) - 使用以下代码以 . 分隔的第一列,我无法获取它。

相反,只打印了一个新行。

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;

【问题讨论】:

  • . 是一个正则表达式元字符,你需要使用它的字面意思对其进行转义
  • 亚伦,谢谢你的建议!我已经使用了下面的,我仍然无法得到它。我的 ($v1, $v2, $v3) = split("\.",$COLUMN_FIELDS1[0]);打印 $v1,"\n";

标签: arrays perl split


【解决方案1】:

split 将正则表达式作为其第一个参数。您可以将字符串传递给它(就像在您的代码中一样),但字符串的内容将在运行时简单地解释为正则表达式。

这对于,(在正则表达式中没有特殊含义)来说不是问题,但它会与.(匹配正则表达式中的任何(非换行符)字符)中断。

您尝试使用split "\." 解决问题的尝试失败了,因为"\.""." 相同:反斜杠具有其正常的字符串转义含义,但由于. 在字符串中不是特殊的,因此对其进行转义没有影响。您只需打印结果字符串即可看到这一点:

print "\.\n";  # outputs '.', same as print ".\n";

. 然后被解释为正则表达式,导致您观察到的问题。

正常的解决方法是将正则表达式传递给split

split /\./, $string

现在反斜杠被解释为正则表达式的一部分,强制. 与自身匹配。

如果你真的想传递一个字符串来分割(我不确定你为什么要这样做),你也可以这样做:

split "\\.", $string

第一个反斜杠转义第二个反斜杠,给出一个双字符串 (\.),当解释为正则表达式时,它的含义与 /\./ 相同。

【讨论】:

  • melpomene,我已经尝试过你的建议,它对我有用..谢谢。
【解决方案2】:

如果您查看split() 的文档,您会发现它提供了以下调用函数的方法:

拆分 /PATTERN/,EXPR,LIMIT

拆分/PATTERN/,EXPR

拆分/PATTERN/

拆分

在其中三个示例中,函数的第一个参数是/PATTERN/。也就是说,split() 期望得到一个正则表达式,它定义了输入字符串的拆分方式。

意识到这个参数是一个正则表达式,而不是一个字符串是非常重要的。不幸的是,Perl 的解析器并不坚持这一点。它允许您使用看起来像字符串的第一个参数(就像您所做的那样)。但无论它看起来如何,它都不是一个字符串。这是一个正则表达式。

所以你用这样的代码弄糊涂了:

split(".",$COLUMN_FIELDS1[0])

如果您使第一个参数看起来像一个正则表达式,那么您更有可能意识到第一个参数是一个正则表达式,因此需要转义一个点以防止它被解释为元字符。

split(/\./, $COLUMN_FIELDS1[0])

更新: Perl 程序员普遍接受,大写名称的变量是常量,不会改变它们的值。通过对标准变量使用大写名称,您可能会混淆下一个编辑您的代码的人(很可能在六个月后成为您)。

【讨论】:

  • 戴夫,我已经在上面的代码和我的程序中将变量从大写改成了小写,感谢您的上述解决方案和建议。它对我有用..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 2022-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多