我想从字符串中提取一些字段,但我不确定它们有多少。 我使用了正则表达式,但有些问题我不明白。
例如:
199 -> (199)
199,200 -> (199,200)
300,20,500 -> (300,20, 500)
我尝试过,但有些我无法让它发挥作用。 希望有人能给我一些建议。我会很感激。
我试过的正则表达式:
>>> re.match('^(\d+,)*(\d+)$', '20,59,199,300').groups()
('199,', '300')
// in this, I do not really care about ',' since I could use .strip(',') to trim that.
我做了一些谷歌:并试图使用re.findall,但我不知道如何得到这个:
>>> re.findall('^(\d+,)*(\d+)$', '20,59,199,300')
[('199,', '300')]
----------------------------------------------- -------更新
我没有讲完整个故事就意识到这个问题可能令人困惑。 基本上我想验证在crontab(或类似)
中定义的语法我为_VALID_EXPRESSION创建了一个数组:它是一个嵌套的元组。
(field_1,
field_2,
)
对于每个field_1,它有两个元组,
field_1: ((0,59), (r'....', r'....'))
valid_value valid_format
在我的代码中,它看起来像这样:
_VALID_EXPRESSION = \
12 (((0, 59), (r'^\*$', r'^\*/(\d+)$', r'^(\d+)-(\d+)$',
13 r'^(\d+)-(\d+)/(\d+)$', r'^(\d+,)*(\d+)$')), # second
14 ((0, 59), (r'^\*$', r'^\*\/(\d+)$', r'^(\d+)-(\d+)$',
15 r'^(\d+)-(\d+)/(\d+)$', r'^(\d+,)*(\d+)$')), # minute
16 .... )
在我的解析函数中,我所要做的就是提取所有组并查看它们是否在有效值范围内。
我需要的一个正则表达式是它能够正确匹配此字符串'50,200,300'并在这种情况下提取所有数字。 (我当然可以使用split(),然而,它会背叛我的初衷。所以,我不喜欢这个主意。)
希望这会有所帮助。
答案 0 :(得分:3)
为什么不使用string.split?
numbers = targetstr.split(',')
答案 1 :(得分:1)
使用正则表达式的最简单的解决方案是:
r"(\d+,?)"
您可以使用findall
获取所需的300,
,20,
和500
。或者,如果您不想要逗号:
r"(\d+),?"
这匹配一组1个或更多数字,后跟0或1个逗号(不在组中)。
无论哪种方式:
>>> s = '300,20,500'
>>> r = re.compile(r"(\d+),?")
>>> r.findall(s)
['300', '20', '500']
然而,正如Sahil Grover指出的那样,如果这些是你的输入字符串,这相当于只调用s.split(',')
。如果您的输入字符串可能包含非数字,那么这将确保您只匹配数字字符串,但即使这样也可能更简单,因为filter(str.isdigit, s.split(','))
。
如果您需要tuple
int
而不是list
str
s:
>>> tuple(map(int, r.findall(s)))
(300, 20, 500)
如果您发现理解/生成器表达式比map
/ filter
调用更容易阅读:
>>> tuple(int(x) for x in r.findall(s))
(300, 20, 500)
或者更简单:
>>> tuple(int(x) for x in s.split(',') if x.isdigit())
(300, 20, 500)
如果你想要字符串(300, 20, 500)
,当然你可以通过调用repr
上的tuple
来做到这一点,那么有一种更容易实现的方法:
>>> '(' + s + ')'
'(300, 20, 500)'
你原来的正则表达式:
'^(\d+,)*(\d+)$'
...将准确返回两个组,因为模式中只有两个组。而且,由于您明确将其包含在^
和$
中,因此必须匹配整个字符串,因此findall
不会帮助您 - 它会找到完全相同的一个匹配(两个组)为match
。