我有一种特定格式的数据(从splunk>中导出),它是CSV和命名字段的混合体。我想了解Python是否有可能通过模板(或简化的,人类可理解的正则表达式)来解析这些数据
"Harry Potter", "book", "12 Mar 2014 note=""good"" language=""English"""
"Forrest Gump", "movie", "14 March 2015 note=""good"" language=""Aztec"""
正如您所看到的,第一个字段以逗号分隔,然后是一个以日期开头的长字符串,然后我有一些命名字段(note
,language
)。
我想仅从命名字段构建一个dicts列表:
[
{'note': 'good', 'language'='English'},
{'note': 'good', 'language'='Aztec'}
]
在解析CSV之后,我最后得到了最后一个字段(例如第一行的"12 Mar 2014 note=""good"" language=""English"""
),然后我陷入困境,我能想到的唯一解决方案是尝试描述正则表达式中的行(其中很可怕:)。即使我设法提取元组,如何将它们翻译成字典?
答案 0 :(得分:3)
csv
模块将为您提供开箱即用的外部和加倍引用。您的列具有外引号(确保保留值中的分隔符,引号和换行符),并且值中的任何引号都会加倍; csv.reader()
将删除外部引号并返回第三列的单引号字符串。
命名字段可以通过正则表达式处理:
import csv
import re
keyvalue = re.compile(r'([^"= ]+)="([^"]+)"')
with open(filename, 'rb') as infh:
reader = csv.reader(infh, skipinitialspace=True)
namedfields = [dict(keyvalue.findall(row[2])) for row in reader]
skipinitialspace
选项删除分隔符后的任何空格;这需要确保正确删除引用列值之前的空格,从而确保处理引用。
此处的re.findall()
方法会返回(key, value)
元组的列表,而dict()
类型会将这些直接转换为字典。
演示:
>>> import csv
>>> import re
>>> keyvalue = re.compile(r'([^"= ]+)="([^"]+)"')
>>> sample = '''\
... "Harry Potter", "book", "12 Mar 2014 note=""good"" language=""English"""
... "Forrest Gump", "movie", "14 March 2015 note=""good"" language=""Aztec"""
... '''
>>> reader = csv.reader(sample.splitlines(True), skipinitialspace=True)
>>> [dict(keyvalue.findall(row[2])) for row in reader]
[{'note': 'good', 'language': 'English'}, {'note': 'good', 'language': 'Aztec'}]