【问题标题】:Parsing CSV data using a regex in Perl在 Perl 中使用正则表达式解析 CSV 数据
【发布时间】:2013-11-18 00:55:16
【问题描述】:

我有一个 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;

正如预期的那样,它匹配上面行中的第一个逗号分隔值,但是 它也匹配最后一个值0.2323 部分。由于.,我希望这不匹配。

有人可以帮助我使我的正则表达式更具体,这样它就不会找到数字 是在月经之前还是之后?

【问题讨论】:

  • 数字前的逗号是可选的。如果您想要逗号或字符串开头,请使用(?:^|,)
  • 你应该阅读this

标签: regex perl


【解决方案1】:

在程序中强迫常规表达式做太多事情通常是不明智的。很容易得到令人费解且难以理解的代码,而这些代码本可以使用标准 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;

【讨论】:

    猜你喜欢
    • 2010-10-12
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    相关资源
    最近更新 更多