引用テキスト内に二重引用符がある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}")
しかし、動作しませんでした
最初の値の開始時または最後の値の終了時に引用符が発生する場合に備えて、正規表現をもう少し太字にする必要があります。
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
を正しく使用することを心配する必要はありません。
詳細については、 official Ruby regex documentation 。の「アンカー」セクションを参照してください。
ただし、doで出力の一致を置き換える必要がある場合は、次のいずれかを使用できます。
"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>"
…文字列の補間が1回行われるため、gsub
が実行される前。 gsub
のブロック形式を使用すると、一致ごとにブロックが再度呼び出されます。この時点で、グローバル$1
が適切に入力され、使用可能になります。
Edit:Ruby 1.8(なぜそれを使用しているのですか?)
puts csv.gsub(/([^,\n\r])"([^,\n\r])/,'\1""\2')
s
が文字列であると仮定すると、これは機能します:
puts s.gsub(/([^,])"([^,])/, "\\1\"\"\\2")