2012-03-18 91 views

回答

12

echo !grass!將始終回顯當前值,而不需要任何轉義。你的問題是,價值不是你想象的那樣!當您嘗試設置值時發生問題。

正確的轉義序列來設置你的價值是

set "[email protected]##&^!$^^&%%**(&)" 

現在來解釋。您需要的信息被埋在How does the Windows Command Interpreter (CMD.EXE) parse scripts?中。但有點難以遵循。

你有兩個問題:

1)%必須轉義爲%%將線路將被解析的時間。存在或不存在引號沒有區別。延遲擴張狀態也沒有區別。

set pct=% 
:: pct is undefined 

set pct=%% 
:: pct=% 

call set pct=%% 
:: pct is undefined because the line is parsed twice due to CALL 

call set pct=%%%% 
:: pct=% 

2)時,它被分析器的延遲擴展相解析的!文字必須轉義爲^!。如果在延遲擴展期間某行中包含!,則^文字必須作爲^^轉義。但^也必須引用或轉義爲解析器的特殊字符階段的^^。由於CALL會使任何^字符翻倍,這可能會變得更加複雜。 (對不起,描述問題非常困難,解析器很複雜!)

setlocal disableDelayedExpansion 

set test=^^ 
:: test=^ 

set "test=^" 
:: test=^ 

call set test=^^ 
:: test=^ 
:: 1st pass - ^^ becomes^
:: CALL doubles ^, so we are back to ^^ 
:: 2nd pass - ^^ becomes^

call set "test=^" 
:: test=^^ because of CALL doubling. There is nothing that can prevent this. 

set "test=^...!" 
:: test=^...! 
:: ! has no impact on^when delayed expansion is disabled 

setlocal enableDelayedExpansion 

set "test=^" 
:: test=^ 
:: There is no ! on the line, so no need to escape the quoted ^. 

set "test=^!" 
:: test=! 

set test=^^! 
:: test=! 
:: ! must be escaped, and then the unquoted escape must be escaped 

set var=hello 
set "test=!var! ^^ ^!" 
:: test=hello^! 
:: quoted^literal must be escaped because ! appears in line 

set test=!var! ^^^^ ^^! 
:: test=hello^! 
:: The unquoted escape for the^literal must itself be escaped 
:: The same is true for the ! literal 

call set test=!var! ^^^^ ^^! 
:: test=hello^! 
:: Delayed expansion phase occurs in the 1st pass only 
:: CALL doubling protects the unquoted^literal in the 2nd pass 

call set "test=!var! ^^ ^!" 
:: test=hello ^^ ! 
:: Again, there is no way to prevent the doubling of the quoted^literal 
:: when it is passed through CALL 
+0

很好的解釋。謝謝! – user1077213 2012-03-19 22:27:42

+0

是否有需要轉義的角色列表?例如'*','('etc.? – user1077213 2012-03-20 07:40:36

2

正如dbenham所說,它只是作業。
您可以像dbenham顯示的那樣使用轉義,這是必要的,因爲在您設置值時EnableDelayedExpansion處於活動狀態。
因此,您需要轉義感嘆號,因爲行中有一個感嘆號,脫字符號必須轉義,引號在這種情況下是無用的。
但您也可以在之前設置值您激活EnableDelayedExpansion,
然後您不需要插入符號。

+0

因此,例如,如果在啓用延遲擴展之前設置該值,「@ ##&!$ ^&%**(&)」的轉義形式將如何顯示? – user1077213 2012-03-20 07:43:21

+2

@ user1077213 - 只要該值被引用,只有%需要加倍:'set「grass = @ ##&!$ ^&%% **(&)」'。如果沒有引號,則需要許多轉義:'set grass = @ ## ^&!$ ^^^&%% **(^&)'只要不在括號內就可以工作,如果括號是激活的,那麼關閉'' '也必須轉義:'set grass = @ ## ^&!$ ^^^&%% **(^&^)'。 – dbenham 2012-03-20 14:30:43

+0

這是有道理的。謝謝! :) – user1077213 2012-03-20 14:42:21

相關問題