如何从无空格单词中提取重复模式?Python正则表达式求助
按重复子串模式分割无空格字符串
你之前用的正则r"(\D)\1*"思路偏了——它只能匹配连续重复的单个非数字字符(比如"AAAA"会拆成["AAAA"]),但没法识别"VRJAM"这种由不同字符组成的重复子串,或者首尾重复的模式。
针对你给出的两种场景,这里提供对应的解决思路:
1. 处理完全由子串重复构成的字符串(如"VRJAMVRJAM")
用正则匹配重复的基础子串,再按子串长度分割:
import re def split_full_repeat(s): # 匹配由某个子串重复至少2次构成的整串 match = re.match(r'^(.+)\1+$', s) if match: unit = match.group(1) return [unit] * (len(s) // len(unit)) return [s] # 测试 print(split_full_repeat("VRJAMVRJAM")) # 输出: ['VRJAM', 'VRJAM']
2. 处理首尾有重复子串、中间为其他内容的字符串(如"PANGOLINUPANGO")
从最长的可能子串开始检查,找到首尾相同的最大子串后分割:
def split_head_tail_repeat(s): max_len = len(s) // 2 # 从最长可能的长度倒序检查,确保取到最长的首尾重复子串 for n in range(max_len, 0, -1): if s[:n] == s[-n:]: return [s[:n], s[n:-n], s[-n:]] return [s] # 测试 print(split_head_tail_repeat("PANGOLINUPANGO")) # 输出: ['PANGO', 'LINUP', 'PANGO']
整合两种场景的通用函数
把上面两个逻辑结合,优先检查完全重复的情况,再处理首尾重复:
def split_by_repeat_pattern(s): # 先判断是否为完全重复的字符串 full_match = re.match(r'^(.+)\1+$', s) if full_match: unit = full_match.group(1) return [unit] * (len(s) // len(unit)) # 再判断是否存在首尾重复子串 max_len = len(s) // 2 for n in range(max_len, 0, -1): if s[:n] == s[-n:]: return [s[:n], s[n:-n], s[-n:]] # 无重复模式则返回原字符串 return [s] # 测试两个示例 print(split_by_repeat_pattern("VRJAMVRJAM")) # ['VRJAM', 'VRJAM'] print(split_by_repeat_pattern("PANGOLINUPANGO")) # ['PANGO', 'LINUP', 'PANGO']
补充说明
- 完全重复的正则
^(.+)\1+$:^和$锁定整串匹配,(.+)捕获重复的基础子串,\1+表示该子串至少重复1次(加上首次出现,整串至少包含2次重复)。 - 首尾重复的检查逻辑:从字符串长度的一半倒序遍历,能优先匹配到最长的首尾重复子串,避免误拆分更短的重复片段。
内容的提问来源于stack exchange,提问作者SK_33
相关产品推荐
相关产品推荐

