2011-09-27 67 views
2

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

,因为第一部分是快乐与空字符串匹配您的正则表达式失败,第二部分失败(这是正常,因为它是可选的),所以第三部分捕获所有。解决办法:第一部分匹配任何东西到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. 
+0

是的,可以解决我的问题!我以前没有遇到过(?!)。 – chobok

+0

看看这个[教程](http://www.regular-expressions.info/lookaround.html)。 Lookaround是一个很棒的功能。 –

+0

这是和优秀的教程。真的很好写和全面。谢谢 – chobok

1

你可以这样说:

try: 
    re.search(r'(.*?)(HELLO|BYE)(.*?END)', r'qweHELLOsdfsEND').groups() 
except AttributeError: 
    print 'no match' 
+0

+1:如果您想在它那里提取出来,并做其他事,当它不存在,那么*是不是真正的“可选” *。正则表达式可能会很棘手,因为你经常需要一次推理几个不同的层次。 –

相关问题