处理不一致结构化字符串的更好方法是什么?

时间:2017-10-27 12:35:34

标签: python string parsing

我有一个像这样的输出字符串:

read : io=131220KB, bw=14016KB/s, iops=3504, runt=  9362msec

我想提取一个计算数值,比如说iops。我正在处理它:

        if 'read ' in key:
            my_read_iops = value.split(",")[2].split("=")[1]
            result['test_details']['read'] = my_read_iops

但是我正在阅读的一些字符串存在轻微的不一致,而且我的代码变得非常复杂和冗长。因此,不是手动计算逗号与“=”字符的数量,有什么更好的方法来处理它?<​​/ p>

3 个答案:

答案 0 :(得分:1)

如果我是你,我会使用正则表达式(正则表达式)作为首选。

import re
s= "read : io=131220KB, bw=14016KB/s, iops=3504, runt=  9362msec"
re.search(r"iops=(\d+)",s).group(1)

通过这个python代码,我找到了开始的字符串模式&#39; iops =&#39;并继续数字表达至少1位数。我使用圆括号提取目标字符串(3504)。 你可以从

找到有关正则表达式的更多信息

https://docs.python.org/3.6/library/re.html#module-re

正则表达式是复杂模式匹配的强大语言,语法简单。

答案 1 :(得分:1)

您可以使用正则表达式@Column(name = "path") @javax.persistence.Convert(converter = PathConverter.class) private Path path; 来处理不一致的间距,它匹配零个或多个空格:

\s*

使用group name,您可以从列名列表中构造模式字符串,并执行以下操作:

import re
s = 'read : io=131220KB, bw=14016KB/s, iops=3504, runt=  9362msec'

for m in re.finditer(r'\s*(?P<name>\w*)\s*=\s*(?P<value>[\w/]*)\s*', s):
    print(m.group('name'), m.group('value'))
# io 131220KB
# bw 14016KB/s
# iops 3504
# runt 9362msec

通过这种方式,您只需要更改names = ['io', 'bw', 'iops', 'runt'] name_val_pat = r'\s*{name}\s*=\s*(?P<{group_name}>[\w/]*)\s*' pattern = ','.join([name_val_pat.format(name=name, group_name=name) for name in names]) # '\s*io\s*=\s*(?P<io>[\w/]*)\s*,\s*bw\s*=\s*(?P<bw>[\w/]*)\s*,\s*iops\s*=\s*(?P<iops>[\w/]*)\s*,\s*runt\s*=\s*(?P<runt>[\w/]*)\s*' match = re.search(pattern, s) data_dict = {name: match.group(name) for name in names} print(data_dict) # {'io': '131220KB', 'bw': '14016KB/s', 'runt': '9362msec', 'iops': '3504'} 并保持订单正确。

答案 2 :(得分:-1)

from re import match
string = 'read : io=131220KB, bw=14016KB/s, iops=3504, runt=  9362msec'
iops = match(r'.+(iops=)([0-9]+)', string).group(2)
iops
'3504'