有点老套的解决方案:通过跟踪和错误操作字符串
观察:描述-值对由, 分隔。
所以让我们尝试在这些分隔符处拆分字符串:
line = "Connection=Cable with connector, M12x1-Male, 4-pin, 0.30
m, Version=Background light, Dimension=43 x 9.5 x 64.5 mm, Rated operating volt
age Ue DC=24 V, Current draw max.=208 mA, Operating mode=Normal, Material=Alumin
um anodized, black Glass PMMA, Illumination area=25 x 25 mm, Light type=LED Red
light, Wave length=617 nm, Illuminence (0.1 m)=350 Lux, Beam angle=40 ° x 40 °,
Ambient temperature=-10...55 °C, Approval/Conformity=CE; EAC; WEEE, IP rating=IP
54"
line.split(', ')
是否有逗号 (,) 后面没有空格?让我们检查一下拆分结果是否仍然包含逗号:
>>> any(',' in part for part in line.split(', '))
False
好的。
观察:描述和值用=分隔。
让我们检查我们识别的所有部分是否包含=:
>>> all('=' in x for x in line.split(', '))
False
嗯。发生了什么?我们来看看完整的结果:
>>> line.split(', ')
['Connection=Cable with connector',
'M12x1-Male',
'4-pin',
'0.30 m',
'Version=Background light',
'Dimension=43 x 9.5 x 64.5 mm',
'Rated operating voltage Ue DC=24 V',
'Current draw max.=208 mA',
'Operating mode=Normal',
'Material=Aluminum anodized',
'black Glass PMMA',
'Illumination area=25 x 25 mm',
'Light type=LED Red light',
'Wave length=617 nm',
'Illuminence (0.1 m)=350 Lux',
'Beam angle=40 ° x 40 °',
'Ambient temperature=-10...55 °C',
'Approval/Conformity=CE; EAC; WEEE',
'IP rating=IP54']
啊哈:好像有些值包含, :
Cable with connector, M12x1-Male, 4-pin, 0.30 m
Aluminum anodized, black Glass PMMA
这些也被拆分了。
让我们简单地重新加入这些:
fake_parts = line.split(', ')
real_parts = []
for part in fake_parts:
if '=' in part:
real_parts.append(part)
else:
real_parts[-1] += f', {part}'
看起来怎么样?
>>> real_parts
['Connection=Cable with connector, M12x1-Male, 4-pin, 0.30 m',
'Version=Background light',
'Dimension=43 x 9.5 x 64.5 mm',
'Rated operating voltage Ue DC=24 V',
'Current draw max.=208 mA',
'Operating mode=Normal',
'Material=Aluminum anodized, black Glass PMMA',
'Illumination area=25 x 25 mm',
'Light type=LED Red light',
'Wave length=617 nm',
'Illuminence (0.1 m)=350 Lux',
'Beam angle=40 ° x 40 °',
'Ambient temperature=-10...55 °C',
'Approval/Conformity=CE; EAC; WEEE',
'IP rating=IP54']
>>> all('=' in part for part in real_parts)
True
好多了!
现在是否所有部分都只包含一个=?让我们尝试将它们分开:
>>> all(len(part.split('=')) == 2 for part in real_parts)
True
很好。有了它,我们可以组成一个字典:
>>> from collections import OrderedDict
>>> OrderedDict(part.split('=') for part in real_parts)
OrderedDict([('Connection', 'Cable with connector, M12x1-Male, 4-pin, 0.30 m'),
('Version', 'Background light'),
('Dimension', '43 x 9.5 x 64.5 mm'),
('Rated operating voltage Ue DC', '24 V'),
('Current draw max.', '208 mA'),
('Operating mode', 'Normal'),
('Material', 'Aluminum anodized, black Glass PMMA'),
('Illumination area', '25 x 25 mm'),
('Light type', 'LED Red light'),
('Wave length', '617 nm'),
('Illuminence (0.1 m)', '350 Lux'),
('Beam angle', '40 ° x 40 °'),
('Ambient temperature', '-10...55 °C'),
('Approval/Conformity', 'CE; EAC; WEEE'),
('IP rating', 'IP54')])
或者干脆
>>> dict(part.split('=') for part in real_parts)
{'Ambient temperature': '-10...55 °C',
'Approval/Conformity': 'CE; EAC; WEEE',
'Beam angle': '40 ° x 40 °',
'Connection': 'Cable with connector, M12x1-Male, 4-pin, 0.30 m',
'Current draw max.': '208 mA',
'Dimension': '43 x 9.5 x 64.5 mm',
'IP rating': 'IP54',
'Illumination area': '25 x 25 mm',
'Illuminence (0.1 m)': '350 Lux',
'Light type': 'LED Red light',
'Material': 'Aluminum anodized, black Glass PMMA',
'Operating mode': 'Normal',
'Rated operating voltage Ue DC': '24 V',
'Version': 'Background light',
'Wave length': '617 nm'}
现在这可能是您可以使用的东西。但是,这种方法很脆弱:
- 如果某些描述还包含
, ,怎么办?
- 如果描述或值包含
=,该怎么办?
- 如果格式包含特定的转义序列怎么办?
正确的解决方案:使用解析器
要根据复杂(或不那么复杂)的规则集正确解释编码为文本的数据,请使用解析器库。参见例如How best to parse a simple grammar? 用于选项。
这需要您指定控制编码的确切规则集(称为“语法”),因此也需要了解这些规则。通过查看编码数据是否可以以及如何得出这些规则,取决于该数据。