質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Amazon Athena

Amazon Athenaは、標準SQLを使用してAmazon S3内のデータを直接分析することができるインタラクティブなクエリサービスです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

7920閲覧

Python  csv内のダブルクォーテーションで囲まれたフィールドの中の 『エスケープされていないダブルクォーテーション』をエスケープしたい

DelphiumG

総合スコア3

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Amazon Athena

Amazon Athenaは、標準SQLを使用してAmazon S3内のデータを直接分析することができるインタラクティブなクエリサービスです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2022/04/19 02:53

編集2022/04/19 03:39

ある取引先から連携されたCSVをAWSのAthenaで取り扱いたいのですが、タイトルにあるように

csv内のダブルクォーテーションで囲まれたフィールドの中の 『エスケープされていないダブルクォーテーション』が原因で
ただしく、フィールドが認識できず困っています。
(取引先ではCOBOLによってCSVを生成しているらしく、上記は仕様のため変更不可らしいので、こちらで変換するしかありません)

そこでpythonでCSVを処理して、望ましい形(”が\でエスケープされた)CSVに変換したいのですが、
うまく出来ず、ご教授いただけましたら幸いです。

実現したいこととしては、
下記1.のような元データのCSVを
下記4.のような望ましい形式のCSVに変換することです

1.元データのCSVのイメージ'imput.csv'

1,2,3,"問題箇所"",123,"E"

2.試したスクリプト

import csv from csv import reader, writer with open('input.csv', encoding="utf-8") as fin: with open('output.csv', "w", encoding="utf-8", newline='') as fout: wt = writer( fout, delimiter=',', # 区切り文字をカンマで指定 quotechar='"', # 囲い文字をダブルクォーテーションで指定 escapechar='\\', # escape文字を指定 quoting=csv.QUOTE_MINIMAL # クオート ) for row in reader( fin, delimiter=',', # 区切り文字をカンマで指定 quotechar='"', # 囲い文字をダブルクォーテーションで指定 quoting=csv.QUOTE_MINIMAL # クオート ): output_row = [] for col in row: output_row.append(str(col)) wt.writerow(output_row)

3.上記スクリプトの処理結果(失敗)'output.csv'

1,2,3,"問題箇所"",123,E"""

※問題箇所の後ろの”がエスケープされてしまい、Eの後ろの”もエスケープされて、『問題箇所",123,E"』という一つのフィールドとして
認識されてしまっている。

4.望ましいCSVのイメージ

1,2,3,"問題箇所\"",123,"E"

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

一応、CSV reader/writer の双方に doublequote=False を指定すると望ましい結果に近い出力を得ることができます。

python

1import csv 2from csv import reader, writer 3 4with open('input.csv', encoding="utf-8") as fin: 5 with open('output.csv', "w", encoding="utf-8", newline='') as fout: 6 wt = writer( 7 fout, 8 delimiter=',', # 区切り文字をカンマで指定 9 quotechar='"', # 囲い文字をダブルクォーテーションで指定 10 escapechar='\\', # escape文字を指定 11 quoting=csv.QUOTE_NONNUMERIC, # クオート 12 doublequote=False, 13 ) 14 n = 0 15 created_at = "" 16 for row in reader( 17 fin, 18 delimiter=',', # 区切り文字をカンマで指定 19 quotechar='"', # 囲い文字をダブルクォーテーションで指定 20 doublequote=False, 21 ): 22 output_row = [] 23 for col in row: 24 output_row.append(col) 25 wt.writerow(output_row)

output.csv

csv

1"1","2","3","問題箇所\"","123","E"

なお、CSV reader にも quoting=csv.QUOTE_NONNUMERIC を付けると、仕様によって float 型のインスタンスに変更されてしまいます。

csv

11.0,2.0,3.0,"問題箇所\"",123.0,"E"

投稿2022/04/19 04:11

melian

総合スコア20574

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DelphiumG

2022/04/19 07:20 編集

ご回答ありがとうございます! >一応、CSV reader/writer の双方に doublequote=False を指定すると望ましい結果に近い出力を得ることがで>きます。 なるほどです!! CSVライブラリでも設定次第で、該当CSVを処理することもできるのですね!! 回答いただきましたスクリプトを試したところ、 確かに望んだ結果近い内容になっていることが確認出来ました!! CSV writer,reader のパラメータによる動作の違いについて 理解を深めることができました。 ありがごうとざいました。
guest

0

ベストアンサー

CSVライブラリは、正しい書式のCSVファイルしか読めないので、間違った形式のファイルを読むのは無理でしょう。

カジュアルには、正規表現で「前後どちらも[カンマ,行頭,行末]でない二重引用符」をエスケープするという前処理をしてファイルを作り直せば多くの場合は良いと思いますが、

Python

1import re 2a = '1,2,3,"問題箇所"",123,"E"' 3# 先頭・末尾にカンマを付加して後でそれを取り除く 4b = re.sub('(?<!,)"(?!,)', r'\"', f",{a},") 5print(b[1:-1]) 6 7または、改行込みの場合は、 8 9a = '1,2,3,"問題箇所"",123,"E"\n' 10# 先頭にカンマを付加して後でそれを取り除く 11b = re.sub('(?<!,)"(?![,\n])', r'\"', f",{a}") 12print(b[1:])

それで駄目なデータもある場合は、先頭から1文字ずつ、今は引用符の中なのか外なのかを把握しながら、見ていくしか無いでしょうね。間違った形式にも対応したCSVパーサーを自分で書くという事です。

投稿2022/04/19 03:59

otn

総合スコア85768

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DelphiumG

2022/04/19 04:45 編集

迅速なご対応、ありがとうございます!! >CSVライブラリは、正しい書式のCSVファイルしか読めない なるほどです。このような場合、CSVライブラリは使えないのですね!!  >正規表現で「前後どちらも[カンマ,行頭,行末]でない二重引用符」をエスケープするという前処理 やはりこのような場合は、正規表現による変換を使うわけですね。 『否定後読み』、『否定先読み』 をつかって、ヒットした、『”』を エスケープした文字に置き換えるということですね。 大変勉強になりました。 ベストアンサーとさせていただきました。 今回は改行込のCSVのため、後者のスクリプトを利用して下記のようにスクリプトを 修正したらうまく変換できました。 ```python with open('input_csv', 'r') as fin: with open('output_qiita_new.csv', "w", encoding="utf-8", newline='') as fout: file_data = fin.readlines() for row in file_data: # 先頭にカンマを付加して後でそれを取り除く new_row = re.sub('(?<!,)"(?![,\n])', r'\"', f",{row}") fout.write(new_row[1:]) ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問