2012-03-18 63 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

相关问题