查找被懒惰正则包围的字符串可选中间部分

2 投票
2 回答
1599 浏览
提问于 2025-04-17 03:10

我正在使用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

你的正则表达式出错了,因为第一部分可以匹配空字符串,第二部分匹配失败(这没关系,因为它是可选的),所以第三部分就捕获了所有内容。解决办法是让第一部分匹配到HELLOEND之前的任何内容:

>>> 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.

撰写回答