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

如何用Python正则表达式递归提取代码中所有带括号的标识符(含函数调用、控制语句)

如何用Python正则表达式递归提取代码中所有带括号的标识符(含函数调用、控制语句)

嘿,你想要的效果完全可以通过递归正则实现!Python的re模块支持递归匹配,刚好能解决你这种嵌套括号的场景,咱们一步步来梳理:

先明确你的核心需求

你需要提取所有紧跟在(前面的合法标识符——不管括号里是空的、有内容,还是嵌套了其他括号,这些标识符包括函数名(比如func1)、控制语句关键字(比如if)。

分析你之前尝试的问题

你之前写的正则要么匹配范围太宽泛(比如.*?(?=\s?\()会抓到很多无关的字符串片段),要么方向不对(第二个正则是在匹配括号内部的内容,而非括号前的标识符),所以没得到预期结果。

解决方案:递归正则表达式

我们可以写一个能识别嵌套括号的正则,同时精准捕获括号前的标识符:

import re

string = "int a = {0}; func1(arg1, arg11); if(var1 == data1 && func2(arg2)) {  var2 = func3(arg3, func4(arg4))  func5(var5) } else { (void)func6(arg6) }"

# 递归正则,专门匹配带括号的标识符
pattern = r'\b([a-zA-Z_]\w*)\s*\((?:[^()]|(?R))*\)'
result = re.findall(pattern, string)
print(result)

运行这段代码,输出正好是你想要的:
['func1', 'if', 'func2', 'func3', 'func4', 'func5', 'func6']

正则逻辑拆解

咱们来拆一下这个正则为什么能 work:

  • \b:单词边界,确保我们匹配的是完整的标识符(不会抓到其他字符串的片段)
  • ([a-zA-Z_]\w*):捕获组,匹配Python合法标识符(以字母/下划线开头,后面跟字母、数字、下划线)
  • \s*:匹配括号前可能存在的空格(比如if (var1)里的空格)
  • \(:匹配左括号
  • (?:[^()]|(?R))*:非捕获组,处理括号内部的内容:要么是非括号字符,要么递归匹配整个正则模式(完美解决嵌套括号的问题,比如func3(arg3, func4(arg4))里的func4也能被识别)
  • \):匹配对应的右括号

关于递归正则的说明

你问的“Is there any way to recursively call regex?”——当然可以!Python的re模块支持两种递归方式:

  1. (?R):直接引用整个正则模式,就像我们上面用的那样
  2. 命名分组+(?P=group_name):如果你的正则有命名分组,可以用这种方式递归引用特定分组

一些注意事项

  • 这个正则假设你的代码括号都是成对闭合的,如果有语法错误(比如未闭合的括号),可能会匹配出错
  • 它不会区分字符串中的括号(比如print("hello (world)")里的括号会被误判),如果要处理这种复杂场景,更推荐用Python的ast模块(抽象语法树)来解析代码,比正则更可靠
  • 像(void)这种前面没有标识符的括号结构,不会被捕获,符合你的需求

备注:内容来源于stack exchange,提问作者d_k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 12:13:09