regex Negative Lookbehind匹配范围限制及可变字符支持问题咨询
解决方案
方案1:适配支持长度受限可变后行断言的引擎(Python/.NET/PCRE2等)
绝大多数现代正则引擎都支持最大长度不超过限制的可变长度负向后行断言,你只需要把后行检索的范围限制在water前方30个字符以内即可,正则如下:
(?i)^.*(?<!.{0,25}\bnever\b)water.*$
逻辑说明:
(?i)开启不区分大小写匹配\bnever\b加单词边界避免误匹配到nevermind、forever这类包含never的单词(?<!.{0,25}\bnever\b)负向后行断言,要求water之前的30个字符范围内(最多25个任意字符加5个字符的never,合计最大长度30)不存在独立的never单词- 前后加
.*匹配water前后的任意内容,实现整行匹配的效果
你也可以根据需要调整后行的范围,比如要限制20个字符内没有never,就把{0,25}改成{0,15}即可。
方案2:适配不支持可变后行断言的引擎(JavaScript等)
如果你的运行环境不支持可变长度后行,可以用正向负向预查结合的方式实现,正则如下:
(?i)^(?:(?!\bnever\b.{0,25}water).)*$
逻辑说明:
从行首开始逐字符检查,不存在「never后面跟0-25个字符再跟water」的情况,只要整行存在符合要求的water就会匹配。
测试用例验证
上述两个正则都能完美匹配你给出的预期场景:
- ✅
water匹配 - ✅
I have water匹配 - ❌
I never have water不匹配 - ✅
Where is the water.匹配 - ❌
I never have food or water不匹配 - ✅
I never have food but I always have water匹配 - ✅
I never have food or chips. I like to walk. I have water匹配
原有正则问题说明
你之前写的(?i)^(?=.*?(?:water))(?:(?!never).)*$要求整行所有位置都不能出现never,只要行内有never就全部排除,自然会把never距离water很远的合法场景也误杀。
内容的提问来源于stack exchange,提问作者Shawn Jamal
相关产品推荐
相关产品推荐

