与subst一起使用的Tcl regsub会产生意外结果

时间:2017-05-16 04:49:42

标签: regex tcl

编辑: 我试图取代" xor_in0"使用" xor_in [0]"和" xor_in1"用" xor_in [1]"对于给定的str参数。这里" xor_in0"," xor_in1"是传入的参数,我将其表示为"键"," xor_in [0]"," xor_in [1]"是存储在数组中的value参数。请注意,这里的重点是更换每个"键"在" str"用"值" 。这是我的测试代码:

set str "(xor_in0^xor_in1)"
set str1 "xor_in0^xor_in1" # another input
set key "xor_in0"
set value "xor_in\[0\]"
set newstr ""
set nonalpha  "\[^0-9a-zA-Z\]"
regsub -all [subst {^\[(*\]($key)($nonalpha+)}] $str [subst -nobackslashes {$value\2}] newstr
puts $newstr

但不知怎的,它不起作用......我也试图删除[subst ...]但它仍然无法匹配任何东西。这在某种程度上反对我对正则表达的了解。请帮忙。

3 个答案:

答案 0 :(得分:2)

对我来说,一切似乎都有些过于复杂。

让我们看一下你实际要执行的regsub。这很容易做到这一点;如果您的命令是:

regsub -all [subst {^\[(*\]($key)($nonalpha+)}] $str [subst -nobackslashes {$value\2}] newstr

然后我们可以打印出它将要尝试的内容:

puts [list regsub -all [subst {^\[(*\]($key)($nonalpha+)}] $str [subst -nobackslashes {$value\2}] newstr]

这表明你真的这样做:

regsub -all {^[(*](xor_in0)([^0-9a-zA-z]+)} (xor_in0^xor_in1) {xor_in[0]\2} newstr

那里看起来有点奇怪的部分是RE末尾的([^0-9a-zA-z]+)。这是合法的但奇怪,因为我们可以用\W写一些不同的东西来匹配非alpha:

regsub -all {^[(*](xor_in0)(\W+)} $str {xor_in[0]\2} newstr

这似乎有效。那可能是什么错误呢? nonalpha的定义,因为您正在使用"\[^0-9a-zA-z\]"而不是"\[^0-9a-zA-Z\]"是的,文字^位于ASCII(和Unicode)中)范围从Az ...

OTOH,我实际上希望转变真的像这样:

set newstr [regsub -all {(\y[a-zA-Z]+_in)(\d+)} $str {\1[\2]}]

你不习惯的唯一事情是\y(单词边界约束)和\d(匹配任何数字)。或者,对于简单的转换(将文字子字符串的所有实例映射到另一个文字子字符串):

set newstr [string map [list $key $value] $str]

答案 1 :(得分:0)

实际上我的问题的真正问题是A-z错字:)

答案 2 :(得分:0)

简单通常更好:

regsub -all {\d+} $s {[&]} s

照顾你的例子。