21

引用テキスト内に二重引用符を含む csv ファイルの内容があります

test,first,line,"you are a "kind" man",thanks
again,second,li,"my "boss" is you",good

コンマが前後にないすべての二重引用符を "" に置き換える必要があります

test,first,line,"you are a ""kind"" man",thanks
again,second,li,"my ""boss"" is you",good

したがって、" は "" に置き換えられます

私は試した

x.gsub(/([^,])"([^,])/, "#{$1}\"\"#{$2}")

しかし、うまくいきませんでした

4

2 に答える 2

47

引用符が最初の値の先頭または最後の値の末尾にある場合に備えて、正規表現はもう少し太字にする必要があります。

csv = <<ENDCSV
test,first,line,"you are a "kind" man",thanks
again,second,li,"my "boss" is you",good
more,""Someone" said that you're "cute"",yay
"watch out for this",and,also,"this test case"
ENDCSV

puts csv.gsub(/(?<!^|,)"(?!,|$)/,'""')
#=> test,first,line,"you are a ""kind"" man",thanks
#=> again,second,li,"my ""boss"" is you",good
#=> more,"""Someone"" said that you're ""cute""",yay
#=> "watch out for this",and,also,"this test case"

上記の正規表現は、Ruby 1.9で使用可能なネガティブルックビハインドおよびネガティブルックアヘッドアサーション(アンカー)を使用しています。

  • (?<!^|,)—このスポットの直前には^、行頭()またはコンマを使用しないでください。
  • "—二重引用符を見つける
  • (?!,|$)—このスポットの直後には、コンマまたは行末($)があってはなりません。

\1ボーナスとして、実際にはどちらの側の文字もキャプチャしなかったので、置換文字列で正しく使用することを心配する必要はありません。

詳細については、Ruby正規表現の公式ドキュメントの「アンカー」のセクションを参照してください。


ただし、出力の一致を置き換える必要がある場合、次のいずれかを使用できます。

"hello".gsub /([aeiou])/, '<\1>'            #=> "h<e>ll<o>"
"hello".gsub /([aeiou])/, "<\\1>"           #=> "h<e>ll<o>"
"hello".gsub(/([aeiou])/){ |m| "<#{$1}>" }  #=> "h<e>ll<o>"

次のように、置換文字列で文字列補間を使用することはできません。

"hello".gsub /([aeiou])/, "<#{$1}>"
 #=> "h<previousmatch>ll<previousmatch>"

…文字列補間は、が実行される前gsubに1回行われるためです。ブロック形式を使用するとgsub、一致ごとにブロックが再起動されます。この時点で、グローバル$1が適切に入力され、使用できるようになります。


編集:Ruby 1.8の場合(一体なぜそれを使用しているのですか?)、次を使用できます:

puts csv.gsub(/([^,\n\r])"([^,\n\r])/,'\1""\2')
于 2012-02-01T16:46:20.883 に答える
9

s文字列であると仮定すると、これは機能します。

puts s.gsub(/([^,])"([^,])/, "\\1\"\"\\2")
于 2012-02-01T16:02:22.723 に答える