变量名中的字符转义

4

有人能解释一下cmd如何处理以下示例中的插入符号(carats)吗?

C:\>set ^^=test

C:\>echo %^%
test

C:\>echo ^%^%
test

C:\>echo %^^%
%^%

我想%^%会被简单地处理成%%。我认为变量扩展在考虑插入符号之前进行处理,但这只是一个问题的半吊子答案,我相信它可以更优雅地解释。
在批处理中 -
@echo off
set ^^=test
echo %^%
echo ^%^%
echo %^^%

--

C:\>test.bat
test
test
ECHO is off.
2个回答

3
这是因为批处理处理每个命令行的顺序不同。简单来说,变量扩展是在分析特殊字符之前执行的。这就是为什么插入符号在被删除作为转义字符之前会被变量扩展消耗掉的原因。这也是为什么百分号必须通过自己的转义字符%%来进行转义,而不是标准的插入符号^转义字符。

阶段/顺序

1) 阶段(百分比):

  • 双倍的 %% 会被替换为单个的 %
  • 参数变量的扩展 (%1, %2, 等等)
  • %var% 的扩展,如果 var 不存在,则用空字符串替换它
  • 要完整解释,请参考 dbenham 的这篇文章 同一主题: 百分号扩展

1.5) 从行中删除所有的 <CR> (回车符 0x0d)

2) 阶段(特殊字符, " <LF> ^ & | < > ( )): 查看每个字符

  • 如果是引号 (") 则切换引号标记,如果引号标记处于活动状态,则以下特殊字符不再是特殊字符: ^ & | < > ( )
  • 如果是脱字符 (^),则下一个字符没有特殊含义,脱字符本身被删除,如果脱字符是行的最后一个字符,则追加下一行,下一行的第一个字符始终被处理为转义字符。
    • <LF> 立即停止解析,但不要在前面加上脱字符

如需全面而详细的解释(请务必收藏此链接!),请参见以下答案:


3
此外,根据David Ruhrmann的回答……您需要创建一个名为^的变量,因为解析器将转义第二个脱字符并删除语句set ^^=test中的第一个脱字符。
正如David所解释的那样,百分号扩展阶段是第一阶段,因此它可以扩展甚至像<CR>这样奇怪的表达式,但这也是为什么您无法构建多行百分号扩展的原因。
首先扩展百分号(并因只有一个而失败),然后使用多行脱字符来附加下一行。
echo %va^
r%

但是下一个插入符的例子真的很令人困惑。
set "^=one caret"
set "^^=two carets"
echo "%^%"
call echo "%%^%%"

输出结果为:
"one caret"
"two carets"

这是因为使用CALL会使插入符号被加倍。


对于set命令的精彩解释以及关于尖角符号调用命令行为的补充,点赞 +1。 - David Ruhmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接