Tcl脚本正则表达式匹配结果不符,请求调试
Tcl正则提取文件信息的问题调试
问题背景
目标行格式示例:
+ ROUTED M12 10000 + SHAPE STRIPE ( 22636 * ) ( 41810 89000 )
其中ROUTED可替换为FIXED/COVER/SHIELD,需要提取以下内容:
- 左括号前的整段前缀(包含开头空格)
- 第一个括号内的两个值:
22636、* - 第二个括号内的两个值:
41810、89000
原代码执行后输出错位,Vxx被错误赋值为ROUTED,且缺失89000字段。
错误原因分析
- string match语法误用:Tcl的
string match不支持|正则交替语法,原条件{*ROUTED*|*FIXED*|*COVER*|*SHIELD*}无法正确匹配目标行,仅因字符串包含ROUTED才进入分支,逻辑存在错误。 - 正则捕获组错位:原正则中
(ROUTED|FIXED|COVER|SHIELD)是一个捕获组,导致匹配后该组的值被赋给Vxx,后续字段依次错位;同时第二个括号内的89000因没有对应变量接收而丢失。 - 冗余变量赋值:
set match1 $match1这类语句完全多余,regexp匹配后已直接为变量赋值。
修正后的代码
# 替换原string match为regexp检查,正确匹配包含指定关键词的行 if {[regexp {(ROUTED|FIXED|COVER|SHIELD)} $line]} { # 调整正则:将ROUTED等的分组改为非捕获组,确保捕获组顺序对应需要提取的字段 set RE {(\s*\+\s*(?:ROUTED|FIXED|COVER|SHIELD)[^(]+\(\s*)([^\s()]+)\s+([^\s()]+)\s*\)\s*\(\s*([^\s()]+)\s+([^\s()]+)\s*\)} # 匹配时用对应变量接收所有目标字段 if {[regexp $RE $line -> prefix val1 val2 val3 val4]} { puts $prefix puts $val1 puts $val2 puts $val3 puts $val4 } }
代码说明
- 行匹配条件修正:用
regexp {(ROUTED|FIXED|COVER|SHIELD)} $line替代原string match,准确识别包含目标关键词的行。 - 正则捕获组优化:把
(ROUTED|...)改为非捕获组(?:...),避免该组占用捕获位置,确保后续捕获组直接对应需要提取的数值。 - 变量数量匹配:增加变量接收第二个括号内的第二个值,保证所有目标字段被正确赋值。
验证结果
执行修正后的代码,针对示例行输出:
+ ROUTED M12 10000 + SHAPE STRIPE ( 22636 * 41810 89000
与预期输出完全一致。
内容的提问来源于stack exchange,提问作者san269605
相关产品推荐
相关产品推荐

