Sublime中^\s*def\s+(\w+)\s*\(.+漏匹配嵌套函数和装饰器方法,因默认单行模式下.不匹配换行符,且^/$不跨行锚定;需启用. matches newline并改用(?s)或[\s\S]*?等跨行写法。

为什么 ^\s*def\s+(\w+)\s*\(.+ 会漏掉嵌套函数和装饰器下的方法
Sublime 的正则引擎默认是单行匹配,^ 和 $ 只锚定每行开头结尾,但 Python 中常见装饰器写法(如 @staticmethod)或换行参数会让函数定义跨多行。直接用 ^\s*def\s+(\w+)\s*\(.+ 会因贪婪匹配或断行失败而跳过这些情况。
更关键的是:Sublime 默认不启用「dotall」模式(即 . 不匹配换行符),所以跨行的 def 声明根本不会被整块捕获。
- 必须开启
. matches newline(菜单 → Find → Replace → 点击右下角.*按钮) - 避免用
.+匹配函数体,改用非贪婪.*?防止跨到下一个def - 装饰器行要兼容:允许前面有任意空白或
@开头的行,但不能强制要求——否则带空行或注释时又失效
真正能覆盖大多数 Python 方法定义的正则表达式
这个表达式兼顾可读性、健壮性和 Sublime 实际支持能力:
^\s*(?:@\w+(?:\([^)]*\))?\s*\n\s*)*def\s+(\w+)\s*\([^)]*\):
说明:
-
^\s*:行首可能有缩进 -
(?:@\w+(?:\([^)]*\))?\s*\n\s*)*:零次或多次装饰器行(支持带括号参数如@app.route("/")),每行后跟换行+可选空白 -
def\s+(\w+)\s*\([^)]*\)::核心匹配,[^)]*比.*?更安全,防止误吞闭合括号前的换行
替换为:$1(只保留方法名),勾选 Regular expression 和 . matches newline。
遇到 async def 或类方法(self/cls)怎么办
原表达式不支持 async def,且无法区分实例方法、类方法、静态方法——但提取「所有方法名」本身不需要区分语义,只需扩展关键词即可。
- 把
def改成(?:async\s+)?def,就能匹配async def fetch_data - 类方法名仍以
def开头,无需额外处理;self和cls是参数名,不影响函数声明行的结构 - 如果想排除
__init__这类特殊方法,可在替换前加过滤:查找时用def\s+(?!__\w+__)\w+,但注意 Sublime 正则不支持变长负向先行断言,只能用def\s+(__\w+__|\w+)后手动删
导出结果时容易忽略缩进和重复问题
直接替换为 $1 会把所有方法名挤在原位置,导致混乱。正确做法是先「全部查找」(Find All),再复制结果到新标签页,此时 Sublime 会按匹配顺序列出每行一个方法名。
- 查找后按
Ctrl+Shift+G(Windows/Linux)或Cmd+Shift+G(macOS)跳转到所有匹配处,再Ctrl+Shift+K删除整行(保留方法名),但更稳的是用「Find All」+「Copy All」 - 结果里可能出现重复(比如同一方法被不同正则分支匹配两次),用 Sublime 的「Edit → Permute Lines → Sort Lines (case sensitive)」+「Remove Duplicate Lines」快速去重
- 如果文件含字符串字面量里恰好有
def xxx((极少见但可能),这个正则会误抓——没银弹,人工扫一眼输出比追求 100% 自动更可靠
复杂项目里方法定义形态太多,正则只是初筛工具;真要完整解析,得用 ast 模块。但对快速梳理脚本或小模块,上面这套已足够准且快。

















