我有以下数据,这些数据使用\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})
不幸的是,这是错误的,因为它认为分隔符是一个空格(即使我增加了缓冲区大小,这也是错误的。)
确定分隔符和换行符是否比使用该模块更准确?
答案 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'