You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MicroPython线程中re.search触发递归深度超限错误排查与解决

问题描述

由于MicroPython未提供re.findall(),自行实现了如下替代函数:

def findAll(pattern, s, flags = 0):
    found = []
    while True:
        m = re.search(pattern, s, flags)
        if m:
            g = m.groups()
            s = s[m.span()[1]:]
            found.append(g[0] if len(g) == 1 else g)
        else: 
            return found

该函数在CPython及MicroPython单线程环境下测试正常,但在Pico-W的子线程中调用时触发异常:

File "src/platforms/utils.py", line 16, in findAll
  RuntimeError: maximum recursion depth exceeded

(第16行对应循环内的m = re.search(...)语句)

使用的正则模式为'\x01\x05\x02(.+)\x03\x04',待匹配字符串是该模式的一次或多次重复,中间包含类JSON结构的字符串。

原因分析
  • MicroPython的re模块在子线程环境下的栈空间分配有限,正则匹配过程中的递归回溯更容易触达深度限制。
  • 模式中的.+是贪婪匹配,当待匹配内容包含嵌套结构(如类JSON的括号、引号)时,re.search会产生大量回溯递归调用,在子线程的有限栈资源下直接触发超限。
  • 每次循环截取字符串s = s[m.span()[1]:]的操作,若正则边界匹配存在模糊性,可能导致re.search反复处理相似区域,间接累积递归深度。
解决方法
  1. 优化正则模式,减少回溯
    将贪婪匹配的.+改为非贪婪匹配.+?,精准限定匹配边界,避免不必要的递归回溯:
pattern = '\x01\x05\x02(.+?)\x03\x04'
  1. 重构循环逻辑,避免字符串截取
    使用re.search的pos参数指定匹配起始位置,替代字符串截取操作,减少内存开销和潜在的匹配异常:
def findAll(pattern, s, flags=0):
    found = []
    pos = 0
    str_len = len(s)
    while pos < str_len:
        m = re.search(pattern, s, flags, pos)
        if m:
            g = m.groups()
            found.append(g[0] if len(g) == 1 else g)
            pos = m.span()[1]
        else:
            break
    return found
  1. 临时调整递归深度限制(应急方案)
    在子线程初始化时,适当提高递归深度上限(注意Pico-W内存有限,数值不宜过大):
import sys
sys.setrecursionlimit(1000)  # 默认值通常为500左右,按需调整
  1. 拆分长字符串后逐个匹配
    先按结束边界\x03\x04拆分待匹配字符串,再逐个片段匹配,降低单次正则匹配的复杂度:
def findAll(pattern, s, flags=0):
    found = []
    segments = s.split('\x03\x04')
    for seg in segments:
        if seg:
            full_seg = seg + '\x03\x04'
            m = re.match(pattern, full_seg, flags)
            if m:
                g = m.groups()
                found.append(g[0] if len(g) == 1 else g)
    return found

内容的提问来源于stack exchange,提问作者resurrected user

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:52:45