所以,你有一些有点像 CSV 文件的东西,但不是。您可以做的一件事是缩小差距,然后正常处理它——其他人都建议了这样做的方法。您可以做的另一件事是耸耸肩并按原样处理它,而不是 CSV。
在这里,我们在行首有一个 ID,后跟一个逗号。
/^(\d+),/;
然后是任何东西,后跟一个逗号:
/^(\d+),(.+),/
然后是价格,然后是行尾:
/^(\d+),(.+),(\d+(?:\.\d+)?)$/
是的,(.+),
在中间可以使用嵌入式逗号。 +
是贪心的,所以这会从右到左回溯以找到允许模式其余部分匹配的第一个点。
共:
#! /usr/bin/env perl
use common::sense;
while (<DATA>) {
next unless /^(\d+),(.+),(\d+(?:\.\d+)?)$/;
say "ID: $1";
say "Description: $2";
say "Price: $3";
say "----"
}
__DATA__
ID,Description,Price
1234,Good Part,1.23
2345,This is.ok,2.34
3456,Bad Part,with a comma,4.56
而且,有点整洁(虽然名字比他们的名字长......):
#! /usr/bin/env perl
use common::sense;
while (chomp($_ = <DATA>)) {
next if /
^ID,Description,Price\z # allow only this header
| ^\s*\z # and blank lines
| ^\s*\# # and lines containing only a comment
/xi;
/^(?<ID> \d+),
(?<Description> .+),
(?<Price> \d+(?:\.\d+)?)
\z/x or die "Invalid line: $_";
say "$_: $+{$_}" for qw(ID Description Price);
say "----";
}
__DATA__
ID,Description,Price
1234,Good Part,1.23
2345,This is.ok,2.34
# why do we allow this again?
id,description,price
3456,Bad Part,with a comma,4.56
两个输出:
ID: 1234
Description: Good Part
Price: 1.23
----
ID: 2345
Description: This is.ok
Price: 2.34
----
ID: 3456
Description: Bad Part,with a comma
Price: 4.56
----
是的,您需要更改此正则表达式以适应稍有不同的 notCSV,但您还需要更改您的 gap-closer。这就是 notCSV 不好的原因。