2012-10-01 81 views
1

我想從tcl中的字符串變量替換所有特殊字符,包括空格,連字符等,以強調下劃線。字符串替換正則表達式在tcl中不起作用

input: Stack Overflow helps%me(a lot 
    output: Stack_Overflow_helps_me_a_lot 

我寫了下面的代碼,但它似乎並不奏效。

set varname $origVar 
    puts "Variable Name :>> $varname" 
    if {$varname != ""} { 
     regsub -all {[\s-\]\[$^?+*()|\\%&#]} $varname "_" $newVar 
    } 
    puts "New Variable :>> $newVar" 

一個問題是,不是在$ varname的替換的字符串,它被刪除後$ origVar而不是$ VARNAME內遇到的第一個空間中的數據。也沒有存儲在$ newVar中的值。不知道爲什麼,而且我在TCL的書閱讀示例代碼(語法是否正確),並根據它應該是這樣的

regsub -all {[\s-][$^?+*()|\\%&#]} $varname "_" newVar 

,所以我使用了相同的語法,但它沒有工作,給出了與修改$ origVar而不是所需的$ varname值相同的結果。

回答

3

第二個版本更接近。通過將結果放在$newVar中,您實際上設置了一個名爲的變量$newVar,然後您必須通過$$newVar來訪問它(可以這麼說)(在Tcl中無效)。無論如何,這個問題可能是在你的第二個版本中,你似乎沒有逃避某些角色。試試這個:

regsub -all {[\s\-\]\[$^?+*()|\\%&#]} $varname "_" newVar 

另一種方式來組織,儘量減少逃逸是這樣的:

regsub -all {[][\s$^?+*()|\\%&#-]} $varname "_" newVar 

而且,我不知道這是不是太普通,但你也可以試試這個:

regsub -all {\W} $varname "_" newVar 
+0

那麼第二個選項對我來說工作得很好。我沒有嘗試第一個。雖然第三個選項將取代所有非字母數字字符,甚至會包含'_',我認爲這甚至不應該被考慮。感謝您提供的信息。 –

+2

請注意'\ w'包含數字,所以'[^ \ w \ d]'有點多餘。更簡單的方法是用'regsub -all {\ W} $ var「_」new'替換所有非單詞字符 - 請參閱http://tcl.tk/man/tcl8.5/TclCmd/re_syntax.htm –

+2

另請注意如果你沒有指定一個變量,那麼'regsub'(自8.4開始)返回被替換的字符串;當我不需要知道所做的替換次數時(除了使用'-all'時除外),我發現這非常方便。 –

2

另一種解決方案是使用string map命令,這是簡單的:字符串映射命令發生在列表舊/新的字符串:

set varname [string map {% _ (_ " " _} $varname] 

在上面的例子中,爲了簡潔起見,我只用下劃線替換了%,(和space「」。這個解決方案的缺點是舊/新列表可能有點長。優點更容易理解。

+1

+1 - 同意,僅用於此目的的regexp是矯枉過正的。 –