解析空格分隔的,命名字段

时间:2014-03-24 13:20:19

标签: python regex parsing csv dictionary

我有一种特定格式的数据(从splunk>中导出),它是CSV和命名字段的混合体。我想了解Python是否有可能通过模板(或简化的,人类可理解的正则表达式)来解析这些数据

"Harry Potter", "book", "12 Mar 2014 note=""good"" language=""English"""
"Forrest Gump", "movie", "14 March 2015 note=""good"" language=""Aztec"""

正如您所看到的,第一个字段以逗号分隔,然后是一个以日期开头的长字符串,然后我有一些命名字段(notelanguage)。

我想仅从命名字段构建一个dicts列表:

[
    {'note': 'good', 'language'='English'},
    {'note': 'good', 'language'='Aztec'}
]

在解析CSV之后,我最后得到了最后一个字段(例如第一行的"12 Mar 2014 note=""good"" language=""English"""),然后我陷入困境,我能想到的唯一解决方案是尝试描述正则表达式中的行(其中很可怕:)。即使我设法提取元组,如何将它们翻译成字典?

1 个答案:

答案 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'}]