我尝试使用Python的重新库。 从文件中我得到几行包含以条形('|')分隔的元素。我把它们放在一个列表中,我需要的是将数字放在里面以便与它们一起运行。
这将是我要拆分的字符串之一:
>>print(line_input)
>>[240, 7821, 0, 12, 605, 0, 3]|[1.5, 7881.25, 0, 543, 876, 0, 121]|[237, 761, 0, 61, 7, 605, 605]
我打算用方括号之间的每个元素形成一个向量。
我创建了这个正则表达式
>>test_pattern="\|\[(\d*(\.\d+)?), (\d*(\.\d+)?), (\d*(\.\d+)?)]"
但结果有点令人困惑。特别是,结果是
>>vectors = re.findall(test_pattern, line_input)
>>print(vectors)
>>[('240', '', '7821', '', '0', '', '12', '', '605', '', '0', '', '3', ''), ('1.5', '.5', '7881.25', '.25', '0', '', '0', '', '0', '', '0', '', '0', ''), ('23437', '', '76611', '', '0', '', '0', '', '0', '', '605', '', '605', '')]
我不明白白色空间的来源以及为什么小数部分会重复。我知道我几乎得到它,至少,我确定这是一个简单的小细节,但我不明白。
非常感谢你。
答案 0 :(得分:3)
那些空白是空的可能小数。您的vectors
变量包含所有捕获组,无论是否为空。因此,当存在小数时,您将获得外部组(\d*(\.\d+)?)
的一个匹配,以及内部组(\.\d+)?
的一个匹配。使内部成为非捕获组:
(\d+(?:\.\d+)?)
注意:我也将其更改为要求小数点前的数字(如果有)。
答案 1 :(得分:1)
另一种方法(如果输入格式不同可能是非健壮的)这样做的方法是将字符串拆分为'] | ['来获取列表,然后拆分','来获取值:
from decimal import Decimal
input_str = '[240, 7821, 0, 12, 605, 0, 3]|[1.5, 7881.25, 0, 543, 876, 0, 121]|[237, 761, 0, 61, 7, 605, 605]'
# ignore the first and last '[' and ']' chars, then split on list separators
list_strs = input_str[1:-1].split(']|[')
# Split on ', ' to get individual decimal values
int_lists = [[Decimal(i) for i in s.split(', ')] for s in list_strs]
# int_lists contains a list of lists of decimal values, like the input format
for l in int_lists:
print(', '.join(str(d) for d in l))
<强>结果强>:
240, 7821, 0, 12, 605, 0, 3
1.5, 7881.25, 0, 543, 876, 0, 121
237, 761, 0, 61, 7, 605, 605
答案 2 :(得分:1)
regex有它的位置。但是,使用pyparsing编写的语法通常更容易编写 - 并且更易于阅读。
>>> import pyparsing as pp
这些数字就像用数字和句号/句号字符组成的单词。它们可选地后跟逗号,我们可以简单地压制它们。
>>> number = pp.Word(pp.nums+'.') + pp.Optional(',').suppress()
其中一个列表包含一个左方括号,我们将其取消,后跟一个或多个数字(如刚定义的那样),然后是右方括号,我们也会抑制它,然后是可选的条形字符,抑制。 (顺便说一下,这个条在某种程度上是多余的,因为右括号会关闭列表。)
我们将Group
应用于整个构造,以便pyparsing将我们未被压缩的项目组织到我们的单独Python列表中。
>>> one_list = pp.Group(pp.Suppress('[') + pp.OneOrMore(number) + pp.Suppress(']') + pp.Suppress(pp.Optional('|')))
整个列表集只是一个或多个列表。
>>> whole = pp.OneOrMore(one_list)
这是输入,
>>> line_input = '[240, 7821, 0, 12, 605, 0, 3]|[1.5, 7881.25, 0, 543, 876, 0, 121]|[237, 761, 0, 61, 7, 605, 605]'
...我们将其解析为结果r
。
>>> r = whole.parseString(line_input)
我们可以显示结果列表。
>>> r[0]
(['240', '7821', '0', '12', '605', '0', '3'], {})
>>> r[1]
(['1.5', '7881.25', '0', '543', '876', '0', '121'], {})
>>> r[2]
(['237', '761', '0', '61', '7', '605', '605'], {})
更有可能的是,我们希望数字为数字。在这种情况下,我们知道列表中的字符串表示浮点数或整数。
>>> for l in r.asList():
... [int(_) if _.isnumeric() else float(_) for _ in l]
...
[240, 7821, 0, 12, 605, 0, 3]
[1.5, 7881.25, 0, 543, 876, 0, 121]
[237, 761, 0, 61, 7, 605, 605]
答案 3 :(得分:0)
你可以试试这个:
import re
s = "[240, 7821, 0, 12, 605, 0, 3]|[1.5, 7881.25, 0, 543, 876, 0, 121]|[237, 761, 0, 61, 7, 605, 605]"
data = re.findall("\d+\.*\d+", s)
输出:
['240', '7821', '12', '605', '1.5', '7881.25', '543', '876', '121', '237', '761', '61', '605', '605']