3

CSVファイルから、"フィールド,エンクロージャーとして、フィールドセパレーターとして文字列を含む行があります。時々"、フィールドの囲いを壊すデータがあります。これらを削除するための正規表現を探してい"ます。

私の文字列は次のようになります。

my $csv = qq~"123456","024003","Stuff","","28" stuff with more stuff","2"," 1.99 ","",""~;

私はこれを見ました、引用符だけを削除するように指示する方法がわかりません

  1. 文字列の先頭ではありません
  2. 文字列の最後ではありません
  3. 前にない,
  4. が続かない,

このコード行で、3と4を同時に削除するように指示しました。

$csv =~ s/(?<!,)"(?!,)//g;

ただし、先読みと後読みの両方がとして記述されるのが好きではないため、^とをそこに収めることはできません。$(?<!(^|,))

文字列を分割して各要素から引用符を削除する以外に、正規表現だけでこれを実現する方法はありますか?

4

5 に答える 5

10

CSVデータを操作するには、Text :: CSVを使用することをお勧めします-CSVデータには多くの潜在的な複雑さがあります。これは、自分で処理するコードを作成することは可能ですが、試行錯誤されたCPANモジュールがある場合は努力する価値がありません。あなたのためにそれ

于 2012-05-04T09:57:10.550 に答える
4

CSVファイルの解析に正規表現を使用しないでください。CPANは、nickifatが提案するように、 Text :: CSVを使用するか、Text::ParseWordsのような多くの優れたモジュールを提供します。

use Text::ParseWords;  
while (<DATA>) {
chomp;     
my @f = quotewords ',', 0, $_;     
print join "|" => @f; 
}  

__DATA__ 
"123456","024003","Stuff","",""28" stuff with more stuff","2"," 1.99 ","","" 

出力:

123456|024003|Stuff||28 stuff with more stuff|2| 1.99 || 
于 2012-05-04T10:18:37.870 に答える
1

これは機能するはずです:

$csv =~ s/(?<=[^,])"(?=[^,])//g

12また、コンマの前後に少なくとも1つの文字が必要であることを意味します。したがって、ポジティブルックアラウンドです。3そして4、これらの文字はコンマ以外の何でもかまいません。

于 2012-05-04T10:07:03.310 に答える
1

ここで助けてくれてありがとう。二重引用符が埋め込まれた不適切な形式のCSVで問題が発生していました。正規表現の先読み部分にわずかな追加を1つ追加します。そうしないと、行末のnull値が破損します。

(?<=[^,])\"(?=[^,\n])

\ nを追加すると、行末の最後の二重引用符との一致がなくなります。

于 2013-11-14T00:35:14.407 に答える
-1

提案された

$csv =~ s/(?<=[^,])"(?=[^,])//g;

おそらく最良の答えです。これらの高度な正規表現機能がなければ、同じことを行うこともできます

$csv =~ s/([^,])"([^,])/$1$2/g;

また

$csv = join (',', map {s/"//g;"\"$_\""} split (',', $csv));

文字列が適切にフォーマットされていないcsvであることに注意する必要があると思います。csvファイルでは、値内の二重引用符を2倍にする必要があります(http://en.wikipedia.org/wiki/Comma-separated_values)。ご使用のフォーマットでは、値にコンマの近くに引用符を含めることはできません。

csvはそれほど単純な形式ではありません。「実際の」csvを使用する場合は、モジュールを使用する必要があります。それ以外の場合は、コードを簡略化し、csvを実行していないことを明確にするために、おそらくすべての二重引用符を削除する必要があります。

于 2012-05-04T14:32:05.700 に答える