0

我有一个 CSV 文件,其中每一行看起来像这样:

509,,SOME VALUE,0,1,1,0.23

我正在尝试查找所有两位或更多位的数字,这些数字后面可能有也可能没有逗号,然后使用此 Perl 代码将它们放入数组中:

my $file ='somefile.csv';

open my $DATA , "<", $file;
$_ = do {local $/; <$DATA>};
my @A = /,?(\d{2,}),?/g;
close $DATA;

正如预期的那样,它匹配上面行中的第一个逗号分隔值,但它也匹配23最后一个值的部分,0.23. 我希望这不匹配,因为..

有人可以帮助我使我的正则表达式更具体,这样它也不会在期间之前或之后找到数字吗?

4

1 回答 1

2

在程序中强迫常规表达式做太多事情通常是不明智的。很容易得到令人费解且难以理解的代码,而这些代码本可以用标准 Perl 更简单地实现。

将整个文件一次性放入内存也使这个问题比它需要的更尴尬。逐行读取文件通常是最好和最有效的方法。

我建议你写这样的东西。它读取每一行,从末尾修剪换行符,并将split其分隔为字段。然后,所有与您的标准匹配的字段(两个或多个十进制数字)都被过滤掉grep并推送到数组@numbers中。

use strict;
use warnings;

my $file ='somefile.csv';

open my $data , '<', $file;
my @numbers;
while (<$data>) {
  chomp;
  push @numbers, grep /^\d{2,}$/, split /,/;
}
close $data;

print "$_\n" for @numbers;

输出

509

如果您坚持遵循当前计划,那么此替代计划也将起作用。但我希望你看到它远没有我的第一个建议那么清楚。

use strict;
use warnings;

my $file ='somefile.csv';

my $data = do {
  open my $fh, '<', $file;
  local $/;
  <$fh>;
};

my @numbers = $data =~ /(?:,|^)\K(\d{2,})(?=,|$)/gm;
print "$_\n" for @numbers;
于 2013-11-06T17:36:20.260 回答