如何使用*或?捕获字符串与python正则表达式中的组

时间:2012-04-15 04:35:23

标签: python regex grouping capture metacharacters

我下面有str1和str2,我想只使用一个匹配两者的正则表达式。在str1的情况下,我还希望能够捕获QSFP端口的数量

>>> str1='''4 48 48-port and 6 QSFP 10GigE Linecard 7548S-LC''' 
>>> str2='''4 48 48-port 10GigE Linecard 7548S-LC''' 
>>> 

我希望能够捕获数字“4”,“48”,“6”(如果存在)和“7548”。但我无法使用“?”捕获“6”元字符。

当我不使用元字符时,捕获适用于str1,但随后我可以使用此正则表达式,因为它不适用于str2:

>>> re.search(r'^(\d+)\s+(\d+)\s+.*(?:(\d+)\s+QSFP).*\s+(\d+)S-LC', str1, re.I|re.M).group(3) 
'6' 
>>>

即使我使用“+”表示一次出现,它仍然有效,但同样,这对str2不起作用:

>>> re.search(r'^(\d+)\s+(\d+)\s+.*(?:(\d+)\s+QSFP)+.*\s+(\d+)S-LC', str1, re.I|re.M).group(3) 
'6' 
>>>

当我使用“?”时要匹配0或1次出现,即使对于str1:

,捕获也会失败
>>> re.search(r'^(\d+)\s+(\d+)\s+.*(?:(\d+)\s+QSFP)?.*\s+(\d+)S-LC', str1, re.I|re.M).group(3) 
>>>

4 个答案:

答案 0 :(得分:2)

我对这个问题的解释是OP需要一个匹配两个字符串的正则表达式,并返回.group(1)中的数字(如果它存在)(就像在str1中一样)。我认为问题在于他/她无法同时捕获str1中的'6'并且也匹配str2。

我从一些快速的试验和错误中得到了这个:

>>> str1='''4 48 48-port and 6 QSFP 10GigE Linecard 7548S-LC''' 
>>> str2='''4 48 48-port 10GigE Linecard 7548S-LC''' 
>>> re.search(r'^4\s+48\s+.*(?:(\d+)\s+QSFP)|.*-LC', str1, re.I|re.M).group(1)
'6'
>>> re.search(r'^4\s+48\s+.*(?:(\d+)\s+QSFP)|.*-LC', str2, re.I|re.M).group(1)
>>> # no error returned, implying a match was found.

区别在于我“或”非捕获的parens。*

不幸的是,这使得正则表达式更加难以理解,但也许它对您有用。

(编辑完整性)

答案 1 :(得分:1)

我不确定你的要求是什么。

是这样的:

>>> str1 = "hello 12 world"
>>> str2 =  "hello world"
>>> obj = re.search(r'(\d+)',str1)
>>> obj.group(0)
'12'

现在检入str2,其中不包含任何小数值。

>>> obj = re.search(r'(\d+)',str2)
>>> if obj is not None:
...     print obj.group(0)
... else:
...     print "not found"
...
not found
>>>

答案 2 :(得分:1)

  

我希望能够捕获数字“4”,“48”,“6”(如果存在),   和“7548”。但我无法使用“?”捕获“6”   元字符。

如果您避免使用正则表达式,则可以简化您的生活,因为您的查询非常简单。

str1='''4 48 48-port and 6 QSFP 10GigE Linecard 7548S-LC'''
str2='''4 48 48-port 10GigE Linecard 7548S-LC'''
lines = [str1,str2]
nums = []
for l in lines:
    r = []
    bits = l.split()
    last_num = bits.pop()[:-4]
    _ = [r.append(i) for i in bits if i.isdigit()]
    r.append(last_num)
    nums.append(r)

>>> nums
[['4', '48', '6', '7548'], ['4', '48', '7548']]

答案 3 :(得分:0)

我认为问题在于.*占用了QSFP位,并且因为?没有动力让它回溯。将.*更改为非贪婪.*?(令人惊讶的是 - 至少对我来说)并没有帮助。然而,移动非捕获组内的.*可以帮助

>>> re.match(r'^4\s+48\s+(?:.*(\d+)\s+QSFP)?.*-LC', str1, re.I|re.M).group(1)
'6'
>>> re.match(r'^4\s+48\s+(?:.*(\d+)\s+QSFP)?.*-LC', str2, re.I|re.M).group(1)
>>>