2 回答
TA贡献1719条经验 获得超6个赞
我过去发现有用的一种技巧是使用shlex.split:
>>> s = '2013-06-05T11:01:02.955 LASTNAME=Jone FIRSTNAME=Jason PERSONNELID=salalm QID=231412 READER_NAME="CAZ.1 LOBBY LEFT TURNSTYLE OUT" ACCESS_TYPE="Access Granted" EVENT_TIME_UTC=1370480141.000 REGION=UTAH'
>>> split = shlex.split(s)
>>> split
['2013-06-05T11:01:02.955', 'LASTNAME=Jone', 'FIRSTNAME=Jason',
'PERSONNELID=salalm', 'QID=231412', 'READER_NAME=CAZ.1 LOBBY LEFT TURNSTYLE OUT',
'ACCESS_TYPE=Access Granted', 'EVENT_TIME_UTC=1370480141.000', 'REGION=UTAH']
然后我们可以将其变成字典:
>>> parsed = dict(k.split("=", 1) for k in split if '=' in k)
>>> parsed
{'EVENT_TIME_UTC': '1370480141.000', 'FIRSTNAME': 'Jason',
'LASTNAME': 'Jone', 'REGION': 'UTAH', 'ACCESS_TYPE': 'Access Granted',
'PERSONNELID': 'salalm', 'QID': '231412',
'READER_NAME': 'CAZ.1 LOBBY LEFT TURNSTYLE OUT'}
正如@abarnert指出的那样,您可以根据需要保留更多信息:
>>> dict(k.partition('=')[::2] for k in split)
{'2013-06-05T11:01:02.955': '', 'EVENT_TIME_UTC': '1370480141.000', 'FIRSTNAME': 'Jason', 'LASTNAME': 'Jone', 'REGION': 'UTAH', 'ACCESS_TYPE': 'Access Granted', 'PERSONNELID': 'salalm', 'QID': '231412', 'READER_NAME': 'CAZ.1 LOBBY LEFT TURNSTYLE OUT'}
等等。正如他很好地指出的那样,关键点在于,您所显示的语法看起来非常类似于最小化Shell语法。OTOH,如果违反了您在其他地方显示的模式,则您可能希望回过头来编写自定义解析器。该shlex方法适用时很方便,但没有您想要的健壮性。
TA贡献1788条经验 获得超4个赞
让我们分析问题:您要匹配四个标识符之一,然后是一个=符号,然后是带引号的字符串或一系列非空格字符。
对于正则表达式而言,这是一项完美的工作:
>>> s= ' 2013-06-05T11:01:02.955 LASTNAME=Jone FIRSTNAME=Jason PERSONNELID=salal
m QID=231412 READER_NAME="CAZ.1 LOBBY LEFT TURNSTYLE OUT" ACCESS_TYPE="Access Gr
anted" EVENT_TIME_UTC=1370480141.000 REGION=UTAH'
>>> import re
>>> regex = re.compile(r"""\b(PERSONNELID|REGION|ACCESS_TYPE|EVENT_TIME_UTC)
... =
... ("[^"]*"|\S+)""", re.VERBOSE)
>>> result = regex.findall(s)
>>> result
[('PERSONNELID', 'salalm'), ('ACCESS_TYPE', '"Access Granted"'),
('EVENT_TIME_UTC', '1370480141.000'), ('REGION', 'UTAH')]
>>> dict(result)
{'EVENT_TIME_UTC': '1370480141.000', 'PERSONNELID': 'salalm',
'ACCESS_TYPE': '"Access Granted"', 'REGION': 'UTAH'}
解释:
\b确保匹配从单词边界开始。
"[^"]*" 匹配引号,后跟任意数量的非引号字符和另一个引号。
\S+ 匹配一个或多个非空白字符。
通过将正则表达式的“有趣”部分括在括号中,建立捕获组,您可以分别获得匹配项各部分的元组列表。
添加回答
举报