真正學習這次正則知識前,我是被這道題給難住了:
# 目標文本 str1 = "ever1, ever2, never1, never2, never3, forever1, forever2, forever3" # 要求匹配到ever、forever 但是 不要never expected = ['ever1', 'ever2', 'forever1', 'forever2', 'forever3']
方案1
[^n](?:for|)ever\d*
結果:
[' ever2', ' forever1', ' forever2', ' forever3']
由於[^n]即使沒匹配到也會占用一個空格,所以只匹配到4條,第一個ever1無法匹配到(它前面無空格)
因此這里需要的是,不保存結果的匹配,我也叫他為“約束”,自然引來了下一種
方案2:
(?<!n)(?:for|)ever\d* # 此種正則使用了反向預搜索,json不支持
結果:
['ever1', 'ever2', 'forever1', 'forever2', 'forever3']
終於達成目的
Get1:
所以得出了所謂“預搜索”的作用,他只是約束,不參與匹配結果的生成。
同樣作用的,還有(?=pattern) (?!pattern) (?<=pattern) (?<!pattern) \b \B etc
所以我最開始使用的[^n],他哪怕沒有找到任何結果,都要占一個空格的坑,給匹配結果出一份力,就不屬於這類“約束”語句
Get2:
(?:pattern)不屬於上類的預搜索,如例子中:(?:for|)的意思,后面接了for 或者空 他是會直接拼接匹配結果的。
Get3:
(?=pattern) 與 (?<=pattern)的區別,都是預搜索,前者為正向預搜索,后者反向預搜索。談談我的粗陋理解
首先我們假定有個已經定死的,或者已經找到的東東叫book吧,然后以book為坐標原點
book(?=pattern) 匹配得:book(后面滿足pattern)
所以正向匹配,遇到了book先不激動,再向右匹配,看是不是要的那個book,類似於:book(written by LuXun)
(?<=pattern)book 匹配得:(前面滿足pattern的)book
所以逆向匹配,遇到了book后,反着向左匹配,看是不是所要的book, 類似於:(A good )book
最后貼上python代碼,方便練習
str1 = "ever1, ever2, never1, never1, never2, never3, forever1222, forever2, forever3" regex = r"(?<!n)(?:for|)ever\d*" res = re.findall(regex, str1) print(res)