我正在尝试在TCL中使用regsub用数组中的值替换字符串。
array set myArray "
one 1
two 2
"
set myString "\[%one%\],\[%two%\]"
regsub -all "\[%(.+?)%\]" $myString "$myArray(\\1)" newString
我的目标是将字符串从“[%1%],[%2%]”转换为“1,2”。问题是捕获组索引未解析。我收到以下错误:
can't read "myArray(\1)": no such element in array
while executing
"regsub -all "\[%(.+?)%\]" $myString "$myArray(\\1)" newString"
答案 0 :(得分:1)
这是Tcl中的两步过程。你在这里的主要错误是到处使用双引号:
array set myArray {one 1 two 2}
set myString {[%one%],[%two%]}
regsub -all {\[%(.+?)%\]} $myString {$myArray(\1)} new
puts $new
puts [subst -nobackslash -nocommand $new]
$myArray(one),$myArray(two)
1,2
因此我们使用regsub
来搜索表达式,并将其替换为我们要扩展的变量的字符串表示形式。然后我们使用很少使用的subst
命令来执行变量(仅)替换。
答案 1 :(得分:1)
除了使用regsub
+ subst
(一般来说,明确的棘手的命令对一般安全使用)之外,您还可以使用{{1}进行相对简单的转换}}。诀窍在于如何准备映射:
string map
只要您想要往返的每件事物在申请时都是一个常量字符串 ,您就可以使用# It's conventional to use [array set] like this…
array set myArray {
one 1
two 2
}
set myString "\[%one%\],\[%two%\]"
# Build the transform
set transform {}
foreach {from to} [array get myArray] {
lappend transform "\[%$from%\]" $to
}
# Apply the transform
set changedString [string map $transform $myString]
puts "transformed from '$myString' to '$changedString'"
来执行此操作。优势?它显然正确。很难使string map
+ regsub
变换明显正确(但如果您需要更复杂的变换则是必要的;例如,这是在URL中进行%XX编码和解码的正确方法)。