2013-10-30 52 views
0

我試圖用TCL中的regsub替換一個字符串與數組中的值。如何使用正則表達式捕獲組作爲數組索引?

array set myArray " 
one 1 
two 2 
" 
set myString "\[%one%\],\[%two%\]" 

regsub -all "\[%(.+?)%\]" $myString "$myArray(\\1)" newString 

我的目標是一個字符串轉換從 「[%的一種%],[%2%]」,以 「1,2」。問題是捕獲組索引未解決。我收到以下錯誤:

can't read "myArray(\1)": no such element in array 
while executing 
"regsub -all "\[%(.+?)%\]" $myString "$myArray(\\1)" newString" 

回答

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命令來執行變量(唯一)替換。

+0

像冠軍!謝謝! – BakerBug

1

除了用regsub + subst(這是一個決定性的棘手對命令於一般的安全使用),你也可以做使用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 + subst轉換顯然正確(但如果您需要更復雜的轉換,則是必需的;例如,這是在URL中執行%XX編碼和解碼的正確方法)。