递归子串搜索实现求助:忽略标点且返回含标点的起止索引
解决方案
核心实现思路
要满足需求,需要同时处理「忽略非字母数字字符匹配」和「追踪原文本真实索引」两个核心点,关键逻辑包括:
- 遍历原文本时跳过非字母数字字符,但保留其在原文本中的位置信息
- 匹配失败时回退到起始匹配位置的下一位,重新发起搜索,避免误判
- 精准记录匹配的起始索引,以及匹配完成时的结束索引(符合Python切片规则)
修正后的代码
def search(text, sub): # 过滤子串中的非字母数字字符(兼容子串含特殊字符的情况) target_chars = [c for c in sub if c.isalnum()] target_len = len(target_chars) if target_len == 0: return (0, 0) text_length = len(text) match_progress = 0 # 当前匹配到目标子串的第几个字符 start_pos = None # 记录原文本中匹配的起始索引 for idx in range(text_length): current_char = text[idx] # 跳过非字母数字字符 if not current_char.isalnum(): # 若已经在匹配过程中,跳过不影响;未开始匹配则继续找下一个字符 continue # 当前字符是字母数字,进行匹配判断 if current_char == target_chars[match_progress]: if match_progress == 0: # 记录匹配的起始位置 start_pos = idx match_progress += 1 # 匹配完整个子串,返回起止索引 if match_progress == target_len: return (start_pos, idx + 1) else: # 匹配失败,重置状态并回退到起始位置的下一位重新搜索 if match_progress > 0: idx = start_pos match_progress = 0 start_pos = None # 题目明确子串一定存在,此处仅为兜底 return (-1, -1) # 测试示例 result = search("BD ACA;B_ 1E", "AB1") print(result) # 输出 (5, 11)
代码说明
- 子串预处理:先过滤子串中的非字母数字字符,确保匹配逻辑只关注有效字符
- 状态追踪:用
match_progress记录当前匹配进度,start_pos记录原文本中匹配的起始位置 - 匹配与回溯:
- 遇到非字母数字字符直接跳过,不中断已有的匹配进度
- 字符匹配成功则推进进度,匹配完成时返回起止索引
- 匹配失败时回退到起始位置的下一位,重置匹配状态,解决原代码无法重新发起搜索的问题
- 索引规则:结束索引设为匹配字符的下一位,确保
text[start:end]能截取到包含所有被忽略字符的完整片段
对原代码问题的修复
- 移除了调试用的打印语句,聚焦核心功能实现
- 新增匹配失败后的回溯机制,确保只有完整匹配到目标子串才会返回结果
- 实现了起止索引的精准追踪与返回,完全符合题目示例要求
内容的提问来源于stack exchange,提问作者KOB
相关产品推荐
相关产品推荐

