我有这个字符串
circle,4.5
square,3.1
circle,2.0
triangle,4.7,4.9
square,4.1
circle,4.3
让我们说我想捕捉形状的名称和它旁边的两个数字。我已经尝试了这个,并将评论我内心的问题:
>>> ma = re.search(r"(\w+)[,(\d+.\d+)]+", "Triangle,3.4,1.2")
>>> ma.group()
'Triangle,3.4,1.2'
>>> ma.group(1)
'Triangle'
>>> ma.group(2) ##Why is this happening ???
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
ma.group(2)
IndexError: no such group
我想我不能把捕获组放在方括号内?
答案 0 :(得分:1)
方括号具有特殊含义。它们旨在创建Character class
..因此,如果您将capture groups
放在方括号内,则表示匹配 group1,或group2,或group3 ..它将不匹配所有群体都是连续性的。你将不得不使用另一个capture group
代替方括号..
但是,您可以在这种情况下使用拆分: -
>>> str = "Triangle,3.4,1.2"
>>> str.split(",")
['Triangle', '3.4', '1.2']
>>>
>>> str = "circle,4.5"
>>> str.split(",")
['circle', '4.5']
>>> str.split(",")[0]
'circle'
>>> str.split(",")[1]
'4.5'
根据你的正则表达式: -
ma = re.search(r"(\w+)[,(\d+.\d+)]+", "Triangle,3.4,1.2")
您使用的字符集[,(\d+.\d+)]
匹配 - ,
或(\d+.\d+)
..
您应将其更改为: -
ma = re.search(r"(\w+)(,(\d+.\d+))+", "Triangle,3.4,1.2")
但在这种情况下存在问题: -
您只创建了3个组: -
group 0 -> complete match
group 1 -> `,1.2` (Outer bracket)
group 2 -> `1.2` (Inner Bracket)
你不会得到3.4
,因为(,(\d+.\d+))
首先匹配 - ,3.4
然后,1.2
..所以,它只会记住,1.2
..
答案 1 :(得分:1)
使用.split(',')
是最简单的方法,但是,如果你想使用正则表达式,那么你应该使用
ma = re.search(r"^([^,]+),([^,]+)(?:,([^,]+))?", "Triangle,3.4,1.2")
答案 2 :(得分:1)
方括号特别;它们将其中的所有字符标记为字符组。您要求匹配数字(\d
),,
逗号,.
句号,(
左括号或)
右括号。换句话说,左右括号是匹配字符的一部分,不表示捕获组。
你根本不需要使用一个字符类,你正在寻找一个更具体的数字模式,完全停止后跟另一个数字。使用非捕获组((?:...)
)将数字格式与逗号分组以匹配重复的数字组:
r"(\w+)(?:,(\d+.\d+))+"
不幸的是,这仍然不会为您捕获多个组;正则表达式永远不会产生可变数量的组。我们在这里只定义了两个组,所以我们得到的只是:
>>> import re
>>> ma = re.search(r"(\w+)(?:,(\d+.\d+))+", "Triangle,3.4,1.2")
>>> ma.groups()
('Triangle', '1.2')
有关遇到此限制的其他SO问题,请参阅Regex question about parsing method signature和python regex repetition with capture question。
您的格式实际上非常简单,并且根据而不是使用正则表达式会更好。简单地用,
逗号分隔并完成它:
>>> "Triangle,3.4,1.2".split(',')
['Triangle', '3.4', '1.2']