如何在Python中解析文本和提取参数值



我有这样的文本文件(它实际上有10000多行(:

Generate placement
Place object 4 at (24,21)
Place object 21 at (89, 4)
Generate movement
At time 10, move object 4 to (3,65) with speed 10
At time 54, move object 21 to (43,6) with speed 4
Generate flux
Set intensity 10, simulation time 5

这里我想从这个文件得到什么:

{
'placement': [{'object_placement': 4, 'location': (24,21)}, 
{'object_placement': 21, 'location': (89, 4)}],
'movement': [{'time': 10, 'object': 4, 'destination': (3,65), 'speed': 10},
{'time': 54, 'object': 21, 'destination': (43,6), 'speed': 4}],
'flux': [{'intensity': 10, 'simulation_time': 5}]
}

我在考虑这个问题,但我不确定在我的情况下是否可以使用Template类或Jinja。

您可以通过在代码中使用一组正则表达式来解析所需格式的数据。这里有一个简单的概念证明。

import re
source = """Generate placement
Place object 4 at (24,21)
Place object 21 at (89, 4)
Generate movement
At time 10, move object 4 to (3,65) with speed 10
At time 54, move object 21 to (43,6) with speed 4
Generate flux
Set intensity 10, simulation time 5"""
results = {
'placement': [],
'movement': [],
'flux': [],
}
state = ""
for line in source.splitlines():
new_state = re.search("Generate ([a-zA-Z]+)", line)
if new_state:
state = new_state.groups()[0]
else:
# Parse the appropriate data for the current state
if state == "placement":
placement_data = re.search("Place object ([0-9]+) at (([0-9]+),s*([0-9]+))", line)
if placement_data:
placement_groups = placement_data.groups()
results[state].append({'object_placement':placement_groups[0], 'location': (placement_groups[1],placement_groups[2])})
elif state == "movement":
movement_data = re.search("At time ([0-9]+), move object ([0-9]+) to (([0-9]+),s*([0-9]+)) with speed ([0-9]+)", line)
if movement_data:
movement_groups = movement_data.groups()
results[state].append({'time':movement_groups[0], 'object': movement_groups[1], 'destination': (movement_groups[2], movement_groups[3]), 'speed': movement_groups[4]})
elif state == "flux":
flux_data = re.search("Set intensity ([0-9]+), simulation time ([0-9]+)", line)
if flux_data:
flux_groups = flux_data.groups()
results[state].append({'intensity': flux_groups[0], 'simulation_time': flux_groups[1]})
print(results)

在上面的示例中,results是包含解析结果的对象。我使用了一个正则表达式,该表达式基于您为placementmovementflux描述的每个状态,以及这些数据在源文本中的格式。

这个想法是对源文本的每一行进行迭代,首先检查状态的变化。如果您不更改状态,那么下面的文本将按照您为相应的当前状态所描述的方式进行格式化。正则表达式对于捕获定义良好的数据格式的特定字段非常有用。最后,使用正则表达式中捕获的数据来填充存储结果的数据结构。

以下是运行上面的代码(格式化(的结果

{
placement: [
{ object_placement: '4', location: '21' },
{ object_placement: '21', location: '4' }
],
movement: [
{ time: '10', object: '4', destination: '65', speed: '10' },
{ time: '54', object: '21', destination: '6', speed: '4' }
],
flux: [ { intensity: '10', simulation_time: '5' } ]
}

请注意,我还没有将解析后的数据转换为数字格式,但使用int()函数可以很容易地完成这一操作。我将把它作为一个练习留给OP来执行。

最新更新