Python Regex - 解析字符串并提取key=value对

0 人关注

我有一些文本,我想从中提取key=value对(见下文)。我曾试图使用一个重构函数,但是键值对的格式并不一致。例如,许多值用引号括起来,有些却没有。

这是一个几乎有效的搜索结果,但有几个异常值。

(\w*)=([\w,\",:,\-,(,\.,\+,\)]*)

信息符合警报条件 date=2020-08-20 time=00:33:57 devname=FGT3HD3999906624 devid=FGT3HD3999906624 logid="0100032003" type="事件" subtype="系统" level="信息" vd="root" eventtime=1597847637407862934 tz="+1000" logdesc="管理员注销成功" sn="159999794" user="admin" ui="https(10.198.199.105)" method="https" srcip=10.198.199.105 dstip=192.168.23.254 action="logout" status="success" duration=4843 reason="timeout" msg="管理员admin在https(10.198.199.105)上超时了" 管理员 IT管理员 Ph:

4 个评论
看起来你不需要用regex来做这个。你为什么认为你需要呢?
我的帖子没有显示出来,但这段文字被埋在电子邮件的正文中,其中包括 "信息符合警报条件 "和 "管理员IT..."。另外,这些字段是动态的,因此需要使用Regex。
python
regex
John Greenfield
John Greenfield
发布于 2020-08-23
2 个回答
jdaz
jdaz
发布于 2020-08-23
已采纳
0 人赞同

你有几个方法可以做到这一点。首先,由于你说你的键值对被嵌入到一个更大的电子邮件中,你需要提取它们。你可以用这个词组来做,它可以检查以一个词和一个等号开始的行。

import re
text = " ... Full email text ... "
dataPoints = re.search(r"^\w*=.*$", text, re.MULTILINE).group(0)

然后你需要创建你的字典。

Option 1: Simplest

Use the following regex find:

result = dict(re.findall(r'(\w*)=(\".*?\"|\S*)', dataPoints))

Regex demo

方案2:典型的分割

按照这个问题的典型方法:把各种键值组合分成一个列表,然后把每个组合分成独立的键和值。然而,由于你的键值对是由空格而不是分号、安培符或类似的东西分隔的,而且你的一些值中有空格,我们不能简单地用空格分割。这意味着我们需要使用一个regex lookahead,这样才能正常工作。

regexSplit = dict([i.split("=") for i in re.split(r"\s(?=\w+=)", dataPoints)])

Option 3: No regex

如果你出于某种原因想完全避免使用 regex,你可以使用下面的方法,它在等号上进行分割,然后将键和值重新组合成适当的排列,以创建一个字典。

allSplits = dataPoints.split("=")
splitList = [allSplits[0]] + [i for a in allSplits[1:-1] 
    for i in a.rsplit(" ", 1)] + [allSplits[-1]]
splitDict = dict(zip(splitList[::2], splitList[1::2]))

上面的代码假定你的字典最终会有至少2个项目。

所有3个选项的演示

谢谢,这样做效果很好,也迎合了字典创作的需要。
Stefan
Stefan
发布于 2020-08-23
0 人赞同

在你的搜索结果中加入一个OR( | )怎么样,比如说

(\w*)=(\"[\w\s\+()\.]*\"|[\w\-\:\.]*)

匹配你给的字符串。