我有以下代码,我试图通过 regexp 函数将单行数据匹配到不同的变量中。 regexp 函数中的数据(在输入行上)和变量名称的数量可能会有所不同,这就是我使用$ varLine(之前在我的实际代码中处理过)的原因。
set in_stim "13 1 1 0 1 0 0 0 2 03"
set regex {^(\d+)\s([01])\s([01])\s([01])\s([01])\s([01])\s([01])\s([01])\s(\d+)\s(\d+)}
set varLine "sig1 sig2 sig3 sig4 sig5 sig6 sig7 sig8 sig8"
regexp $regex $in_stim whole sig0 $varLine
puts "sig0: $sig0"
puts $sig1
当我执行它时,我收到以下错误($ sig0正确显示):
sig0: 13
can't read "sig1": no such variable
while executing
"puts $sig1"
如果我手动将$ varLine替换为regexp行,则错误消失:
set in_stim "13 1 1 0 1 0 0 0 2 03"
set regex {^(\d+)\s([01])\s([01])\s([01])\s([01])\s([01])\s([01])\s([01])\s(\d+)\s(\d+)}
regexp $regex $in_stim whole sig0 sig1 sig2 sig3 sig4 sig5 sig6 sig7 sig8 sig8
puts $sig0
puts $sig1
我得到以下正确的输出:
13
1
有没有人在我的代码中看到错误或者可以提供帮助? 谢谢!
答案 0 :(得分:2)
当你这样做时
set varLine "sig1 sig2 sig3 sig4 sig5 sig6 sig7 sig8 sig8"
regexp $regex $in_stim whole sig0 $varLine
Tcl解析器正好传递regexp
命令的五个参数,第五个参数是变量“varLine”的内容,然后regexp
命令将其视为一个单词。一个单词显然表示一个单独的变量(在您的情况下,名称有点复杂,因为它发生)。
要做你需要的,你必须采用动态脚本,这可以通过两种方式完成:
使用eval
的“经典”方法:
eval [concat [list regexp $regex $in_stim whole sig0] $varLine]
使用Tcl 8.5以后的{*}
句法糖:
regexp $regex $in_stim whole sig0 {*}$varLine
经典方法首先通过连接两个列表来构造单词列表:命令的“静态”部分,然后是传递给它的变量列表。然后构造的列表eval
作为命令。您可以在this classic book中了解详情。
在新式方法中,{*}
thingy用于将$ varLine的内容扩展为“就地”列表 - 请参阅第5条规则here。
答案 1 :(得分:2)
问题是regexp
命令没有将变量列表存储为一个参数,而是存储多个参数。
解决此问题的最简单方法是扩展变量列表:
regexp $regex $in_stim whole sig0 {*}$varLine