为了账号安全,请及时绑定邮箱和手机立即绑定

如何从未格式化的字符串中分离出字符串

如何从未格式化的字符串中分离出字符串

梦里花落0921 2021-03-19 14:11:21
我有这种格式的字符串 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其中一些看起来像这样 2013-06-05T11:15:48.670 LASTNAME=Ga FIRSTNAME="Je " PERSONNELID=jega QID=Q10138202 READER_NAME="CAZ.1 ELEVATOR LOBBY DBL GLASS" ACCESS_TYPE="Access Granted" EVENT_TIME_UTC=1370481333.000 REGION=UTAH我想提取PERSONNELID,REGION,ACCESS_TYPE,EVENT_TIME_UTC的值我本打算使用split(“”),但是READER_NAME和ACCESS_TYPE值有很多空格,我可以转换为JSON并按键搜索提取那些字符串的方法是什么。
查看完整描述

2 回答

?
慕侠2389804

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方法适用时很方便,但没有您想要的健壮性。


查看完整回答
反对 回复 2021-03-30
?
尚方宝剑之说

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+ 匹配一个或多个非空白字符。


通过将正则表达式的“有趣”部分括在括号中,建立捕获组,您可以分别获得匹配项各部分的元组列表。


查看完整回答
反对 回复 2021-03-30
  • 2 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信