2011-09-27 62 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:如果您想在它那裏提取出來,並做其他事,當它不存在,那麼*是不是真正的「可選」 *。正則表達式可能會很棘手,因爲你經常需要一次推理幾個不同的層次。 –

相關問題