目标文本:
ever1, ever2, never1, never1, never2, never3, forever1, forever2, forever3
要求:
匹配ever, forever, 但是不要never
Python代码:
str1 = "ever1, ever2, never1, never1, never2, never3, forever1222, forever2, forever3"
regex = r"(?<!n)(?:for|)ever\d*"
res = re.findall(regex, str1)
print(res)
方案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
正则的?:pattern, ?=pattern, ?!pattern学习整理
原文:https://www.cnblogs.com/july401/p/10908437.html