0
def csv_split() :
    raw = [ 
            '"1,2,3" , "4,5,6" , "456,789"',
            '"text":"a,b,c,d", "gate":"456,789"'
          ]
    cr = csv.reader( raw, skipinitialspace=True )
    for l in cr :
        print len( l ), l

この関数は以下を出力します。

3 ['1,2,3 ', '4,5,6 ', '456,789']
6 ['text:"a', 'b', 'c', 'd"', 'gate:"456', '789"']

ご覧のとおり、最初の行は正しく 3 つのエントリに分割されています。しかし、2行目はそうではありません。csv リーダーがそれを 2 つに分割すると予想されますが、ここでは 6 つになっています。正規表現のアプローチについても考えましたが、特定の引用方言を想定しています。

基本的に私が欲しいのは、「」のペアで引用されていない「、」があるときはいつでも文字列を分割することです。

これを行うための迅速かつ一般的な方法はありますか?すべてのフィールドが常に引用されていることなどを前提とする正規表現のハックを見てきました。これを非常に非効率的に行う小さなループを書くことができると思いますが、より専門的なアドバイスをいただければ幸いです。どうもありがとう!

4

2 に答える 2

2

""CSV は標準化された形式ではありませんが、引用符がテキスト内にある場合は、引用符を 2 つ使用してエスケープするのが一般的です (例: "text"":""a,b,c,d")。Python の CSV リーダーは、この規則を前提としているため、ここでは正しいことをしています。出力として何を期待しているのかよくわかりませんが、フォーマットに適した非常に単純な CSV リーダーを試してみました。それに応じて自由に調整してください。

raw = [
    '"1,2,3" , "4,5,6" , "456,789"',
    '"text":"a,b,c,d", "gate":"456,789"',
    '1,2,  3,'
]

for line in raw:
    i, quoted, row = 0, False, []
    for j, c in enumerate(line):
        if c == ',' and not quoted:
            row.append(line[i:j].strip())
            i = j + 1
        elif c == '"':
            quoted = not quoted
    row.append(line[i:j+1].strip())
    for i in range(len(row)):
        if len(row[i]) >= 2 and row[i][0] == '"' and row[i][-1] == '"':
            row[i] = row[i][1:-1] # remove quotation marks
    print row

出力:

['1,2,3', '4,5,6', '456,789']
['text":"a,b,c,d', 'gate":"456,789']
['1', '2', '3', '']
于 2012-07-09T02:14:35.603 に答える
0

私もこれに少し苦労したので、これを後世のためにここに残します。

へのquotechar引数はcsv.reader()、これを解決するのに役立ちます。delims (つまり、このシナリオではコンマ) が引用符で囲まれている場合は無視できます (エントリ内のすべてのコンマが引用符で囲まれていると仮定します)。つまり、次の場合に機能します。

Name, Message
Ford Prefect, Imagine this fork as the temporal universe.
Arthur Dent, "Hey, I was using that!" 

...カンマは引用符でネストされていますが、カンマで囲まれていない文字列はネストされていません。

Py2 docsからリッピングされたデモ コードdelimiterは、コンマ (duh) でquotecharあり、二重引用符になるように編集されてい"ます。

import csv
with open('eggs.csv', 'rb') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
    for row in spamreader:
        print ', '.join(row)
于 2013-11-09T18:13:39.023 に答える