2017-09-01 33 views
1

这个问题是关于'?'的操作。在我之前的问题中,有人错误地将我的问题标记为重复。所以我重新打开这个问题,要求答案。Python的正则表达式?操作:是否有返回首选项,0或1?

我想问为什么第一个表达式不会从字符串“axxxxxbcd”输出('a','b','c','d')。

import re 
match = re.findall(r'(a).*?(b)?.*?(c)?(d)','awsssd axxxxxbcd ad adfdfdcdfdd 
awsbdfdfdcd') 
print (match) 

输出[1]:[( '一个', '', '', 'd'),( '一个', '', 'C', 'd'),( 'A' , '', '', 'd'),( '一个', '', '', 'd'),( '一个', '', '', 'd')]

import re 

match = re.findall(r'(a).*?(b)?(c)?(d)','awsssd axxxxxbcd ad adfdfdcdfdd awsbdfdfdcd') 
print (match) 

output [2]:[('a','','','d'),('a','b','c','d'),('a','','' ”, 'd'),( '一个', '', '', 'd'),( 'A', 'b', '', 'd')]

@Isaac

+2

你可能想看看https://regex101.com/ –

回答

1

您可以更好地了解什么是在捕获括号包装的正则表达式的每个元素事情:

import re 

rgx1 = re.compile(r'(a)(.*?)(b)?(.*?)(c)?(d)') 
m1 = rgx1.search('axxxxxbcd') 
print(m1.groups()) 

输出:

('a', '', None, 'xxxxxb', 'c', 'd') 

这里发生了什么:

# Group 1: 'a' 
# Group 2: capture as little as possible, so we get '' 
# Group 3: 'b' is not present, but it's optional, so we get None 
# Group 4: 'xxxxxb' 
# Group 5: 'c' 
# Group 6: 'd' 

为什么第4组最终是内容而不是第2组?最初,它们是相同的,捕获尽可能少(没有),但这会导致整体正则表达式失败。所以引擎必须开始扩展第2组或第4组。基于这个例子,看起来引擎首先扩展了后者 - 但我不知道这样的情况具体的实现规则是什么。为了证明这两个组确实在追求非贪婪策略,可以在字符串中添加一个d:例如,使用输入文本axxdxxxbcd。在这种情况下,第4组最终只持有xx

以下办法可以做你想要什么:

rgx1 = re.compile(r'(a)(?:.*?(b)|.*?)(?:.*?(c)|.*?)(d)') 
m1 = rgx1.search('a...b...cd') 
print(m1.groups()) # Output: ('a', 'b', 'c', 'd') 

但我可能不会解决问题的方式。每个(或几乎每个)元素都是可选的正则表达式往往很难正确。有时候你最好在几个简单的阶段解析文本,而不是在一个大毛茸茸的正则表达式中解析。

+0

谢谢。但是我仍然不知道第2组和第4组之间是有区别的。 –

+0

@XiaoboLi这是一个很好的问题。我在答案中增加了另一段。 – FMc

+0

谢谢。我喜欢你的正则表达式解决方案。 –

0

由于 ,您正在获得该输出。*?匹配任何字符(除了行终止

(a).*?(b)?.*?(c)?(d) 

Group 1. 0-1 `a` 
Group 3. 7-8 `c` 
Group 4. 8-9 `d` 

第一捕捉(a)组

一个字符一个字面(区分大小写) 匹配。*?任何字符匹配(除了行终止) ? *量词 - 匹配零和无限倍之间,如几次尽可能,扩大根据需要(懒惰)

第二捕获组(b)

?量词 - 匹配零次和一次,尽可能多次,根据需要回馈(贪婪) b与字面b相符(区分大小写) 。*?匹配任何字符(行结束符除外) *?量词 - 匹配零和无限次,尽可能少的次数,根据需要扩展(懒惰)

3rd捕获组(c)?

?量词 - 匹配次0和1之间,多次地,用之于根据需要(贪婪) c匹配字符c字面上(区分大小写)

第四捕获组(d) d的字符相匹配ð字面上(区分大小写)

但如果你想输出( 'A', 'b', 'C', 'd')从字符串 'axxxxxbcd'

正则表达式应该是

(a).*?(b)?(c)?(d) 

Group 1. 0-1 `a` 
Group 2. 6-7 `b` 
Group 3. 7-8 `c` 
Group 4. 8-9 `d`