Python 解析以空格分隔的命名字段

Python 解析以空格分隔的命名字段,python,regex,parsing,csv,dictionary,Python,Regex,Parsing,Csv,Dictionary,我有一个特定的数据格式(从>)是CSV和命名字段的混合体。我想了解在Python中是否可以通过一个模板(或一个简化的、一般人可以理解的正则表达式)解析这些数据 正如您所看到的,第一个字段是逗号分隔的,然后是一个以日期开头的长字符串,然后我有几个命名字段(注意,语言) 我想仅从命名字段建立一个DICT列表: [ {'note': 'good', 'language'='English'}, {'note': 'good', 'language'='Aztec'} ] 解析CSV后

我有一个特定的数据格式(从>)是CSV和命名字段的混合体。我想了解在Python中是否可以通过一个模板(或一个简化的、一般人可以理解的正则表达式)解析这些数据

正如您所看到的,第一个字段是逗号分隔的,然后是一个以日期开头的长字符串,然后我有几个命名字段(
注意
语言

我想仅从命名字段建立一个DICT列表:

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

解析CSV后,我以最后一个字段结束(例如,第一行为“
”2014年3月12日note=”“good”“language=”“English”“”
),然后我陷入困境,我能想到的唯一解决方案是尝试用正则表达式描述该行(这很可怕:)。即使我成功地提取了元组,如何将它们转换为dict?

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()
方法返回
(键、值)
元组列表,而
dict()
类型将直接将这些元组转换为字典

演示:


如果最后一个字段不是特别复杂,并且按照您指定的格式固定,那么您可以继续使用regex获取数据。命名字段中的文本是否可能包含空格?例如,
note=”“very good”“
@WarrenWeckesser:是的,对不起,我应该说清楚。太好了,非常感谢。我真的需要研究理解,因为它们似乎是某种巫毒,然后变成了一种咒语。@WoJ:列表理解只是从循环中建立列表的一种快捷方式
namedfields=[]
,然后对于读卡器中的行:namedfields.append(dict(keyvalue.findall(row[2]))将是显式循环替代方案。
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]
>>> 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'}]