从python中的文件中获取复杂的输入?

时间:2015-08-02 18:07:45

标签: python python-2.7 python-3.x

我正在开发一个程序,我必须找到一个点位于一个圆圈内,并且数据是由用户给出的。我已经准备好了我的算法,但我很难量化用户给出的特定容器(如列表或字典)的数据。它必须采用如下格式,并通过文件作为参数传递。

Center: (2.12, -3.48); Radius: 17.22; Point: (16.21, -5)

我在下面尝试了这段代码

from sys import argv

file_name = argv[1]
fp = open(file_name,'r+')

contents = [line.strip('\n') for line in fp]
content = [item.split(' ') for item in contents]

#content = fp.read().split(';') #commented

print (contents, '\n' , content)

输出是: -

['Center: (2.12, -3.48); Radius: 17.22; Point: (16.21, -5)']
[['Center:', '(2.12', '-3.48);', 'Radius:', '17.22;', 'Point:', '(16.21,', '-5)']

所以,显然我无法获得那些整数值来解决问题。也是由于添加';' ':'','进一步使情况变得更加复杂。

我应该尝试分别量化每个术语。如果我只能得到那些整数值,有什么办法吗?

3 个答案:

答案 0 :(得分:1)

如果数据是常规的,你可以像这样使用正则表达式:

import re
data = "Center: (2.12, -3.48); Radius: 17.22; Point: (16.21, -5)"
result = re.search('Center: \(([-0-9\.]+), ([-0-9\.]+)\); Radius: ([-0-9\.]+); Point: \(([-0-9\.]+), ([-0-9\.]+)\)', data)
center_x, center_y, radius, point_x, point_y = map(float, result.groups())

答案 1 :(得分:1)

请不要按照lolopop的回答建议使用<?php echo $variable; ?>eval is dangerous

而是使用ast.literal_eval

  

安全地评估表达式节点或包含Python文字或容器显示的Unicode或Latin-1编码字符串。提供的字符串或节点可能只包含以下Python文字结构:字符串,数字,元组,列表,dicts,布尔值和None。

     

这可以用于安全地评估包含来自不受信任来源的Python值的字符串,而无需自己解析值。它无法评估任意复杂的表达式,例如涉及运算符或索引。

一个例子:

eval

输出:

import ast

input_line = "Center: (2.12, -3.48); Radius: 17.22; Point: (16.21, -5)"

center, radius, point = input_line.split(";")
center = ast.literal_eval(center.split(":")[1].strip())
radius = ast.literal_eval(radius.split(":")[1].strip())
point = ast.literal_eval(point.split(":")[1].strip())

print center, radius, point

(2.12, -3.48) 17.22 (16.21, -5) 是第一个元组。 center是单一值。 radius是最后一个元组。

这是在每个值之间以分号(point)拆分字符串。此拆分后;的值为:

center

其他值看起来相似。接下来,我们通过利用冒号(Center: (2.12, -3.48) )上的拆分,在每个拆分的第二部分上使用literal_eval。我们还剥离了前导和尾随空格,因为冒号和值之间有一个空格。如果不这样做,我们会得到一个IndentionException。

答案 2 :(得分:0)

.split('; ')eval怎么样,因为数据几乎是python形式的?它可能很危险,但是如果你想快速完成它并且可以依靠简单的输入。

显然,正确的方式是使用正则表达式,可以通过import re获得:

import re
match = re.match("Center: \(([0-9\.]*), ([0-9\.]*)\); Radius: ([0-9\.]); Point: \(([0-9\.]*), ([0-9\.]*)\)", line)

然后

point = (match.group(0), match.group(1))

不确定正则表达式模式,还没有测试过。文档here