如何正确提取Tcl文件中所有proc定义的过程名(含命名空间)?
提取Tcl代码中的过程名解决方案
问题背景
需要从给定Tcl代码中提取所有过程名,预期结果为fun1 fun2 fun3,但现有正则匹配代码未得到预期输出。
目标Tcl代码示例
namespace eval foo::bar { namespace export fun1 namespace export fun2 } proc foo::bar::fun1 {} { } proc foo::bar::fun2 {} { } proc fun3 {} { }
用户原有实现代码
set f [open $filepath] set data [read $f] close $f foreach {dummy procName} [regexp -all -inline -line {^[\s:]*proc (\S+)} $data] { puts "Found procedure $procName" }
问题分析
原有正则会捕获带命名空间前缀的完整过程名(如foo::bar::fun1),但需求是提取命名空间路径的最后一段过程名;同时正则中的[\s:]*包含多余的冒号匹配,实际proc定义前不会出现冒号前缀。
修正方案
方案1:直接用正则捕获目标过程名
调整正则表达式,可选匹配命名空间前缀,只捕获最后一段过程名:
set f [open $filepath] set data [read $f] close $f foreach {dummy procName} [regexp -all -inline -line {^[\s]*proc (?:.*::)?(\S+)} $data] { puts "Found procedure $procName" }
(?:.*::)?:非捕获组,可选匹配任意字符加命名空间分隔符::,兼容全局空间的proc(\S+):捕获最后一段非空白字符,即目标过程名
方案2:用Tcl内置命令提取短名称
先捕获完整过程名,再通过namespace tail命令提取最后一段(推荐,更符合Tcl惯用写法):
set f [open $filepath] set data [read $f] close $f foreach {dummy fullProcName} [regexp -all -inline -line {^[\s]*proc (\S+)} $data] { set procName [namespace tail $fullProcName] puts "Found procedure $procName" }
namespace tail是Tcl专门用于处理命名空间路径的命令,输入foo::bar::fun1返回fun1,输入fun3直接返回原名称,无需额外正则处理。
运行结果
两种方案执行后均输出:
Found procedure fun1 Found procedure fun2 Found procedure fun3
完全符合预期。
内容的提问来源于stack exchange,提问作者pjariha
相关产品推荐
相关产品推荐

