sud*_*udo 2 python regex search parsing
我有字符串列表,我正在寻找这样的行:
键:af12d9索引:0字段1:1234字段2:1234字段3:-10
在找到这样的行之后,我想将每一个存储为字典{'key':af12d9,'index':0,'field 1':....},然后将这个字典存储到列表中,所以我会有一个词典列表.
我能够让它像这样工作:
listconfig = []
for line in list_of_strings:
matched = findall("(Key:[\s]*[0-9A-Fa-f]+[\s]*)|(Index:[\s]*[0-9]+[\s]*)|(Field 1:[\s]*[0-9]+[\s]*)|(Field 2:[\s]*[0-9]+[\s]*)|(Field 3:[\s]*[-+]?[0-9]+[\s]*)", line)
if matched:
listconfig += [dict(map(lambda pair: (pair[0].strip().lower(), pair[1].strip().lower()),
map(lambda line: line[0].split(':'),
[filter(lambda x: x, group) for group in matched])))]
Run Code Online (Sandbox Code Playgroud)
我只是想知道是否有更好的方法(简短而有效),因为我认为findall每个字符串会进行5次搜索.(对吗?因为它返回了5个元组的列表.)
谢谢.
解:
好的,在brandizzi的帮助下,我找到了这个问题的答案.
解:
listconfig = []
for line in list_of_strings:
matched = re.search(r"Key:[\s]*(?P<key>[0-9A-Fa-f]+)[\s]*" \
r"(Index:[\s]*(?P<index>[0-9]+)[\s]*)?" \
r"(Field 1:[\s]*(?P<field_1>[0-9]+)[\s]*)?" \
r"(Field 2:[\s]*(?P<field_2>[0-9 A-Za-z]+)[\s]*)?" \
r"(Field 3:[\s]*(?P<field_3>[-+]?[0-9]+)[\s]*)?", line)
if matched:
print matched.groupdict()
listconfig.append(matched.groupdict())
Run Code Online (Sandbox Code Playgroud)
首先,你的正则表达式似乎无法正常工作.该Key字段应具有可包含的值f,对吧?所以它的团队不应该([0-9A-Ea-e]+)而是([0-9A-Fa-f]+).此外,在处理正则表达式时,为正则表达式字符串添加前缀是一个很好的 - 实际上是一种奇妙的做法,r因为它避免了\转义字符的问题.(如果您不明白为什么要这样做,请查看原始字符串)
现在,我解决问题的方法.首先,我会创建一个没有管道的正则表达式:
>>> regex = r"(Key):[\s]*([0-9A-Fa-f]+)[\s]*" \
... r"(Index):[\s]*([0-9]+)[\s]*" \
... r"(Field 1):[\s]*([0-9]+)[\s]*" \
... r"(Field 2):[\s]*([0-9 A-Za-z]+)[\s]*" \
... r"(Field 3):[\s]*([-+]?[0-9]+)[\s]*"
Run Code Online (Sandbox Code Playgroud)
通过此更改,findall()将仅返回整个行的已找到组的一个元组.在这个元组中,每个键后跟其值:
>>> re.findall(regex, line)
[('Key', 'af12d9', 'Index', '0', 'Field 1', '1234', 'Field 2', '1234 Ring ', 'Field 3', '-10')]
Run Code Online (Sandbox Code Playgroud)
所以我得到了元组......
>>> found = re.findall(regex, line)[0]
>>> found
('Key', 'af12d9', 'Index', '0', 'Field 1', '1234', 'Field 2', '1234 Ring ', 'Field 3', '-10')
Run Code Online (Sandbox Code Playgroud)
...并使用切片我只得到钥匙......
>>> found[::2]
('Key', 'Index', 'Field 1', 'Field 2', 'Field 3')
Run Code Online (Sandbox Code Playgroud)
......还有唯一的价值观:
>>> found[1::2]
('af12d9', '0', '1234', '1234 Ring ', '-10')
Run Code Online (Sandbox Code Playgroud)
然后我用zip()函数创建一个包含键及其对应值的元组列表:
>>> zip(found[::2], found[1::2])
[('Key', 'af12d9'), ('Index', '0'), ('Field 1', '1234'), ('Field 2', '1234 Ring '), ('Field 3', '-10')]
Run Code Online (Sandbox Code Playgroud)
在大结局是通过元组的列表dict()构造函数:
>>> dict(zip(found[::2], found[1::2]))
{'Field 3': '-10', 'Index': '0', 'Field 1': '1234', 'Key': 'af12d9', 'Field 2': '1234 Ring '}
Run Code Online (Sandbox Code Playgroud)
我发现这个解决方案是最好的,但从某种意义上说它确实是一个主观问题.HTH无论如何:)