与 subst 一起使用的 Tcl 正则表达式会产生意外的结果



编辑: 对于给定的 str 参数,我试图将"xor_in0"替换为"xor_in[0]",将"xor_in1"替换为"xor_in[1]"。这里"xor_in0","xor_in1"是传入的参数,我将其表示为"键","xor_in[0]","xor_in[1]"是存储在数组中的值参数。请注意,这里的重点是将"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 {$value2}] newstr
puts $newstr

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

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

让我们看一下您实际要执行的regsub。有一个技巧可以轻松做到这一点;如果您的命令是:

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

然后我们可以打印出它将尝试做什么:

puts [list regsub -all [subst {^[(*]($key)($nonalpha+)}] $str [subst -nobackslashes {$value2}] 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]"是的,字面^位于从Az的 ASCII(和 Unicode)范围内......


OTOH,我实际上希望转型真正像这样完成:

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

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

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

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

简单通常更好:

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

照顾好你的例子。

最新更新