我需要将一个字符串从2维数组转换为Tcl中的1维。
例如
lane_out[0][7] -> lane_out[7]
lane_out[1][0] -> lane_out[8]
从文件中读取初始字符串,修改并存储在另一个文件中。此外,输入文件有许多不同类型的字符串需要替换,因此用户在另一个文件中提供查找和替换正则表达式。
我已经成功完成了这个简单的字符串,无需额外的计算。但我需要帮助执行表达式。我想我可以让用户在文件中提供表达式并执行该表达式,但我还没有成功。
用户输入文件:
lappend userinput {\[(\d+)]\*$ *}
lappend userinput {\[(\d+)]\[(\d+)]$ [expr{\1*8+\2}]}
我的破码:
set line "lane_out[1][0]"
foreach rule $userinput {
foreach {find replace} [regexp -all -inline {\S+} $rule] break
regsub -all $find $line $replace line
set match [regexp -all -inline {expr{.*}} $line] #match = expr{1*8+0}
set val [$match] #supposed to execute what is in match
regsub expr{.*} $line $val line
}
答案 0 :(得分:4)
你做的事情非常复杂:你有一个输入文件,一组搜索/替换规则,并产生一些输出。但是,规则要求调用expr
。
这是一个虚构的数据文件(data.txt):
lane_out[0][7] = "foo bar"
lane_out[1][0] = "foo bar"
lane_out[1][1] = "foo bar"
lane_out[2][0] = "foo bar"
lane_out[2][1] = "foo bar"
规则文件(rules.txt):
{\[(\d+)\]\[(\d+)\]} {\[[expr {\1 * 8 + \2}]\]}
这是我的脚本(search_replace.tcl):
package require Tclx
# Read the rules file
set rules {}
for_file line rules.txt {
lassign $line find replace
lappend rules $find $replace
}
# Read the data, apply rules
for_file line data.txt {
foreach {find replace} $rules {
regsub -all $find $line $replace line
set line [subst $line]
puts $line
}
}
输出:
lane_out[7] = "foo bar"
lane_out[8] = "foo bar"
lane_out[9] = "foo bar"
lane_out[16] = "foo bar"
lane_out[17] = "foo bar"
代码将翻译一行,例如
lane_out[2][1] = "foo bar"
为:
lane_out\[[expr {2 * 8 + 1}]\] = "foo bar"
然后,subst
命令将其替换为:
lane_out[17] = "foo bar"
棘手的部分是逃避方括号,以便expr
可以做正确的事。