查找被懒惰正则包围的字符串可选中间部分
我正在使用Python和正则表达式来尝试提取字符串中可选的部分。
>>> re.search(r'(.*?)(HELLO|BYE)?(.*?END)', r'qweHELLOsdfsEND').groups()
('', None, 'qweHELLOsdfsEND') #what I want is ('qwe', 'HELLO', 'sdfsEND')
>>> re.search(r'(.*?)(HELLO|BYE)?(.*?END)', r'qweBLAHsdfsEND').groups()
('', None, 'qweBLAHsdfsEND') #when the middle doesn't match. this is OK
我该如何提取这个可选的部分呢?
备注:这是我第一次发帖。
2 个回答
1
你可以这样做:
try:
re.search(r'(.*?)(HELLO|BYE)(.*?END)', r'qweHELLOsdfsEND').groups()
except AttributeError:
print 'no match'
2
你的正则表达式出错了,因为第一部分可以匹配空字符串,第二部分匹配失败(这没关系,因为它是可选的),所以第三部分就捕获了所有内容。解决办法是让第一部分匹配到HELLO
或END
之前的任何内容:
>>> re.search(r'((?:(?!HELLO|BYE).)*)(HELLO|BYE)?(.*?END)', r'qweHELLOsdfsEND').groups()
('qwe', 'HELLO', 'sdfsEND')
>>> re.search(r'((?:(?!HELLO|BYE).)*)(HELLO|BYE)?(.*?END)', r'qweBLAHsdfsEND').groups()
('qweBLAHsdfs', None, 'END')
这样可以吗?
解释:
(?: # Try to match the following:
(?! # First assert that it's impossible to match
HELLO|BYE # HELLO or BYE
) # at this point in the string.
. # If so, match any character.
)* # Do this any number of times.