3

ここで興味深い問題があります。さまざまなベンダーからカンマ区切りファイル (CSV または TSV) として入ってくる、インポートする ID 番号、説明、および価格を含む一般的な価格ファイルがあります。ベンダーの 1 つは、説明フィールドにコンマを使用しています。問題は、すべてのコンマが新しい列を定義し、レコードをスローするとインポートが考えていることです。(インポートファイルが固定長であれば扱いやすいのですが、残念ながらそうではありません。)

質問: 説明のコンマの処理方法を考えられる人はいますか? カンマをピリオドまたはハイフンに置き換えたいと思いますが、これで問題ありません。

ファイルは次のようになります。

ID,Description,Price
1234,Good Part,1.23
2345,This is.ok,2.34
3456,Bad Part,with a comma,4.56

1 番目と 2 番目のレコードには、本来あるべき 3 つの列があります。3 番目の例では、4 列になり、3 番目の列で通貨を探しているため、インポートが中断されますが、代わりに文字列が見つかります。ほとんどの場合、Perl と Java スクリプトを使用しています。

4

5 に答える 5

1

つまり、漠然と CSV ファイルに似ているものがありますが、そうではありません。あなたができることの1つは、ギャップを埋めてから通常どおりに処理することです.他の誰もがこれを行う方法を提案しています. 他にできることは、肩をすくめてそのまま 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 が悪い理由です。

于 2013-06-22T04:02:25.030 に答える
0

フィールドがいくつあるかを知っていて、そのうちの 1 つを除いてすべてを信頼する場合、両端から良い部分を解析することができ、残ったものはすべて悪いフィールドになります。すなわち

while(<>){
 m/(^[^,]+),(.+),([^,]+$)/;
 my @fields = ($1,$2,$3);
 $fields[1]=~s/,/-/g;
}

そのため、最初と最後の固定部分にはカンマが含まれませんが、それらの間の中間フィールドにはカンマが含まれます。

于 2013-06-21T20:16:51.393 に答える
0

これはどう :

 $x='3456,Bad Part,with a comma,4.56';
 @y = split(/,/,$x);
 if ( $#y == 3 ) { 
    $desc = "$y[1],$y[2]";
 };   
于 2013-06-21T19:16:09.350 に答える