Re:RFC 4180対応版 CSVレコードの分解
お題: Server error
投稿: Server error
こんな感じになりました
def csv = '''\ "aaa","b bb","ccc",zzz,"y""Y""y",xxx\ ''' resolveCSV(csv).eachWithIndex{ it, idx -> println "${idx+1} => ${it}" } /** CSVレコードの分解(RFC 4180対応版) */ def resolveCSV(String csv) { csv.split(',').inject(['""']){ result, it -> // 一個前が「半開」ならそこに追加 if (result[-1] ==~ /^".*[^"]$/ || result[-1].count('"') % 2 == 1) { result[-1] = [result[-1], it].join(',') // 「,」で結合 // 一個前が「閉」なら新しく要素を追加 } else { // 「"」で囲んでおく result << ((it =~ /"/) ? it : '""'.toList().join(it)) } result }[1..-1]*.replaceAll(/^"|"$/, '')*.replaceAll(/"{2}/, '"') }
動作確認はGroovy Version: 1.5.7 JVM: 1.6.0_10にて。
入力内容 (上記より)
"aaa","b
bb","ccc",zzz,"y""Y""y",xxx
出力結果
1 => aaa
2 => b
bb
3 => ccc
4 => zzz
5 => y"Y"y
6 => xxx
ポイント
csv.split(',').inject(['""']){ result, it ->
の部分でダミーで ['""']を入れておいて*2
}[1..-1]*.replaceAll(/^"|"$/, '')*.replaceAll(/"{2}/, '"')
の [1..-1] で消し去っています。
その後は、要素に両端のダブルクォート(")を消し去って、更に二重ダブルクォートをダブルクォート(")に置換しています。