在regsub中评估数学

时间:2014-05-13 05:40:32

标签: regex tcl

我需要将一个字符串从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
}

1 个答案:

答案 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" 

讨论

  • rules.txt的格式:每行包含搜索和替换表达式,以空格分隔
  • 代码将翻译一行,例如

    lane_out[2][1] = "foo bar"
    

    为:

    lane_out\[[expr {2 * 8 + 1}]\] = "foo bar"
    
  • 然后,subst命令将其替换为:

    lane_out[17] = "foo bar" 
    
  • 棘手的部分是逃避方括号,以便expr可以做正确的事。

相关问题