匹配ABC开头、BC组合中间、CBA结尾的Python正则表达式优化方案咨询
解决方法:不用
|的Pythonic方案 首先得明确问题核心:你想要匹配的子串是以ABC开头、以CBA结尾,且开头和结尾之间(包括重叠情况)的字符只能是B或C。原来的ABC[BC]*CBA正则之所以匹配不了ABCBA,是因为它要求ABC和CBA必须是不重叠的——ABC之后得先跟若干B/C,再接完整的CBA,但ABCBA里ABC的最后一个C恰好是CBA的第一个C,属于重叠场景,原正则覆盖不到。
下面提供两种不用|的Pythonic解决思路:
1. 纯字符串处理(不用正则)
这种方法更直观,适合不想纠结正则语法的场景:
- 先找出所有
ABC的起始位置 - 对每个起始位置,检查所有可能的结尾位置,确保子串以
CBA结尾,且中间部分(如果有的话)全是B或C - 额外处理重叠的
ABCBA场景
def find_valid_substrings(s): valid_substrings = set() str_len = len(s) # 找到所有"ABC"的起始索引 abc_starts = [i for i in range(str_len - 2) if s[i:i+3] == "ABC"] for start in abc_starts: # 处理重叠情况:直接检查长度为5的子串是否是ABCBA if start + 5 <= str_len and s[start:start+5] == "ABCBA": valid_substrings.add(s[start:start+5]) # 处理非重叠情况:遍历所有可能的结尾,确保子串以CBA结尾 # 子串最小长度为6(ABC + 至少0个B/C + CBA,不重叠) for end in range(start + 6, str_len + 1): # 结尾的三个字符必须是CBA if s[end-3:end] == "CBA": # 检查中间部分(ABC之后到CBA之前)是否全是B/C middle_section = s[start+3 : end-3] if all(char in {"B", "C"} for char in middle_section): valid_substrings.add(s[start:end]) return list(valid_substrings)
测试示例:
print(find_valid_substrings("ABCBA")) # 输出: ['ABCBA'] print(find_valid_substrings("ABCCBA")) # 输出: ['ABCCBA'] print(find_valid_substrings("ABCBBCBA")) # 输出: ['ABCBBCBA'] print(find_valid_substrings("ABCABCBA")) # 输出: ['ABCBA', 'ABCABCBA']
2. 优化后的正则表达式(不用|)
通过零宽断言调整正则逻辑,让它能覆盖重叠场景:
import re pattern = r'(?=(ABC[BC]*?(?<=C)BA))' # 解释: # - (?=...) 正向预查,用于捕获所有可能的匹配(包括重叠) # - ABC 匹配开头 # - [BC]*? 非贪婪匹配任意数量的B/C(尽可能少,避免跳过CBA的起始C) # - (?<=C) 正向断言:确保接下来的BA前面是C(组成CBA) # - BA 匹配结尾的两个字符 # 示例使用 s1 = "ABCBA" print(re.findall(pattern, s1)) # 输出: ['ABCBA'] s2 = "ABCCBA" print(re.findall(pattern, s2)) # 输出: ['ABCCBA'] s3 = "ABCBBCCBA" print(re.findall(pattern, s3)) # 输出: ['ABCBBCCBA']
这种正则通过非贪婪匹配和零宽断言,既覆盖了重叠的ABCBA,也能匹配非重叠的常规场景,不用写|来分支。
内容的提问来源于stack exchange,提问作者MattS
相关产品推荐
相关产品推荐

