如何嗅探CSV行分隔符/终止符(csv.Sniffer()不起作用)

时间:2018-12-17 21:58:15

标签: python python-3.x csv

我有以下数据,这些数据使用\x01作为字段分隔符,并且使用\x02\n作为行分隔符。这是数据示例:

#export_date\x01artist_id\x01name\x01is_actual_artist\x01view_url\x01artist_type_id\x02\n#primaryKey:artist_id\x02\n
#dbTypes:BIGINT\x01INTEGER\x01VARCHAR(1000)\x01BOOLEAN\x01VARCHAR(1000)\x01INTEGER\x02\n#exportMode:INCREMENTAL\x02\n
1475226000146\x011120695691\x01Kinitic SA\x011\x01http://itunes.apple.com/artist/kinitic-sa/id1120695691?uo=5\x017\x02\n

但是,当我尝试使用csv模块进行解析时,会得到以下结果:

with open('myfile', 'r') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    print(dialect.__dict__)
  

mappingproxy({' module ':'csv','_name':'sniffed','lineterminator':'\ r \ n','quoting':0,' doc ”:无,“ doublequote”:False,“ delimiter”:“”,“ quotechar”:“”,“ skipinitialspace”:False})

不幸的是,这是错误的,因为它认为分隔符是一个空格(即使我增加了缓冲区大小,这也是错误的。)

确定分隔符和换行符是否比使用该模块更准确?

1 个答案:

答案 0 :(得分:0)

这是一个非常骇人听闻的东西,但是您可以为这些可能的分隔符计算输入流中的字符数。例如:

import collections

SEPARATORS=['\x00', '\x01', '\x02\n', '^', ':', ',', '\t', ':', ';', '|', '~']

def count_separator(filename, separators=SEPARATORS):
    with open(filename, 'r') as f:
        text = f.read(1024*1024)
    counts = collections.Counter(c for c in text if c in SEPARATORS)
    print (counts)
    return c.most_common()[0][0]

>>> count_separator('/Users/david/Desktop/validate_headers/artist')
Counter({'\x01': 48549, ':': 9752, '\x02': 9741, ',': 295, ';': 3})
'\x01'

上面的badger0053建议的另一种选择是,仅将嗅探器的第一行数据使用。这似乎更好得多:

SEPARATORS=['\x00', '\x01',  '^', ':', ',', '\t', ':', ';', '|', '~', ' ']
LINE_TERMINATORS_IN_ORDER = ['\x02\n', '\r\n', '\n', '\r']
with open('/Users/david/Desktop/validate_headers/artist', 'r') as csvfile:
    line = next(csvfile)
    dialect = csv.Sniffer().sniff(line, SEPARATORS)
    for _terminator in LINE_TERMINATORS_IN_ORDER:
        if line.endswith(_terminator):
            terminator = _terminator
            break
    print(repr(dialect.delimiter), repr(terminator))
  

'\ x01''\ x02 \ n'