如何仅用re.findall正则查找不含QW/WQ的最长子串
正则匹配最长无QW/WQ子串问题
需求
给定仅由英文大写字母组成的字符串,找出其中完全不包含相邻字符组合QW或WQ的最长子串。
要求不使用split或其他辅助方法,仅通过len(max(re.findall(...), key=len))形式的纯正则匹配逻辑实现,确认方案可行性并修正现有正则的错误。
现有代码问题
当前尝试编写的匹配代码如下:
list(map(lambda x: x[0], re.findall(r'(((?<!QW|WQ).)+(?!QW|WQ))', text))
该正则存在匹配错误:会返回以WQ结尾的不合规子串。
测试基准:输入字符串为
WQABCDEFGHQW时,正确的最长合规子串为QABCDEFGHQ,子串内部无任何QW/WQ相邻组合。
可行方案
该纯正则实现方案完全可行。
原有正则的核心问题是:前后的负向断言仅校验了匹配片段首尾外的字符,没有对匹配片段内部的相邻字符组合做约束,导致非法组合漏判。
可用正则与实现代码
直接使用如下正则做匹配即可:
import re longest_sub = max(re.findall(r'[^QW]*(?:Q(?!W)|W(?!Q)[^QW]*)*', text), key=len)
正则逻辑拆解
[^QW]*:先匹配所有不含Q、W的连续字符,这类字符天然不会组成QW/WQ非法组合- 非捕获组
(?:Q(?!W)|W(?!Q)[^QW]*)*循环匹配所有合法的带Q/W的片段:Q(?!W):匹配Q字符,且要求Q后面紧跟的字符不是W,规避QW非法组合W(?!Q)[^QW]*:匹配W字符,且要求W后面紧跟的字符不是Q,规避WQ非法组合,匹配完W后继续向后匹配所有非Q/W的普通字符
- 该正则会自动在所有QW/WQ相邻的位置切断匹配,返回的所有匹配结果都是完全合规的连续子串,直接取长度最大值即可。
效果验证
针对测试用例WQABCDEFGHQW,re.findall返回结果为['', 'QABCDEFGHQ', ''],取长度最大的结果正好是预期的QABCDEFGHQ,符合要求。
内容的提问来源于stack exchange,提问作者Wynell
相关产品推荐
相关产品推荐

