[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[特效代码] [已解决]批处理如何保留变量延迟下的叹号?

问个很菜的问题:如何保留变量延迟下的叹号
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. set "var=虽然现在雷电交加,但是我坚持上bathome"
  4. echo   %var%
  5. echo.
  6. set "war=!!!"!!"!!!^!!^^^!!!!!!%var%"
  7. echo  !!!!!!!!!!!!%war%——!你看见我了吗,我在最前面啊,我是感叹号!~真是悲哀,没人看见我!~
  8. echo.
  9. echo  感叹号!你在哪里呀!在哪里?%war%在这里呀!在这里~!
  10. echo.
  11. pause
复制代码
以上代码只能显示最后一个感叹号,前面的感叹号一个都无法显示,用双引号在某种情况下可以,但是我不想结果里出现双引号,除非能进一步消除双引号。endlocal可以取消定义,问题是在我使用的代码里不能endlocal,否则后面的代码无法执行。
请求高手解答!~
——————————————————————————————————————————
问题已经解决,本人答案在下面 8 楼!~谢谢tireless,虽然我还没认真的去看那个帖子,但它激励我去探讨这个问题。

[ 本帖最后由 cjiabing 于 2009-6-11 22:08 编辑 ]
1

评分人数

    • 随风: 感谢主动给标题加上【已结】PB + 2

简析环境变量和变量延迟特殊字符以及中介法的微妙关系
http://www.cn-dos.net/forum/viewthread.php?tid=30884

TOP

原帖由 tireless 于 2009-6-9 16:12 发表
简析环境变量和变量延迟特殊字符以及中介法的微妙关系
http://www.cn-dos.net/forum/viewthread.php?tid=30884


看了一下,不错,只是看了几天代码现在头疼的很,能不能直接给个答案?

TOP

在没开启变量延迟时设置变量。如:
  1. @echo off
  2. for /f %%a in (a.txt) do (
  3.   set var=%%a
  4.   setlocal enabledelayedexpansion
  5.   echo !var:1=2!
  6.   endlocal
  7. )
  8. pause
复制代码

[ 本帖最后由 tireless 于 2009-6-9 17:10 编辑 ]
1

评分人数

TOP

bjsh版主 ——这个朋友写得不错,相当厉害,只是没有总结好。
hizebra ——这个朋友倒是总结了一下:
『第 18 楼』:  启用变量延迟后,感叹号如何显示?
诚如楼主所言,启用变量延迟后,双感叹号!!间的内容将被替换,若无定义,则echo为空;
试用了 echo "!!!!" 的语句后,显示双引号"";
再试 echo "^!^!!!" 可以显示 "!!";
再试 echo "!^!^!!" 显示为"!";
试 echo "^!!!^!" 显示为"!";
试 echo "!!^!^!" 显示为"!";

由此得到以下规律:
1、脱字符^在字符串首出现时必可显示一个感叹号,后面继续紧跟^!这样的序列组,有多少组就会得到多少个感叹号,直到连续感叹号出现为止;
2、在第一组连续感叹号和最后一个感叹号间的字符串中,只有出现连续^!两组以上的序列,才会得到一个感叹号,有N组就得到N-1个感叹号;即两个脱字符间的感叹号才可被转义。
3、如果把以上echo语句中的双引号取掉,无论任何情况都得不到输出结果。

尽管得到这样的结论,对其内部处理机制仍不是很清楚,请高手答疑。
另外,即使通过这种方法可以显示!,那么怎么取掉外部的双引号呢?请不要简单告诉我输出文件,再用for解析变换,这样得不偿失。我已经尝试用set定义这些echo内容了,然而显示变量为空,不明就里。

TOP

原帖由 tireless 于 2009-6-9 17:09 发表
在没开启变量延迟时设置变量。如:@echo off
for /f %%a in (a.txt) do (
  set var=%%a
  setlocal enabledelayedexpansion
  echo !var:1=2!
  endlocal
)
pause


谢谢支持!问题到现在已经解决了一般,已经得到!,只是不知道是中文状态的还是英文状态的,晚点检查再说。其实这里面涉及到一些规律问题,我搞了半天,按照这个规律才得到结果的,稍晚总结一下,谢谢。

TOP

echo ^^!  

TOP

解决

  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. echo.
  4. echo                   变量延迟中的叹号规则小结
  5. echo.
  6. echo  1、变量延迟下的叹号如果是中文状态,它将被当做字符串显示——问问美国人去!~
  7. echo  2、变量延迟下的叹号如果是英文状态,它将取代正常状态下的百分号 %% 来界定变量。
  8. echo  3、单个叹号将被直接忽略掉。
  9. echo  4、紧邻的两个叹号被定义为变量,叹号连同叹号之间的内容将被忽略掉。
  10. echo  5、P定义两个叹号为一个变量是将从左向右、紧邻、不重叠的一对叹号界定为变量的。
  11. echo  6、两对变量之间的字符串因为未被定义为变量而当做字符串显示。
  12. echo  7、取消变量延迟中的叹号作为变量界定需要用转义符 ^ 。
  13. echo  8、将叹号从变量界定转换为字符串需要用两个转义符 ^^ ^^ 增强(原因?)
  14. echo  9、变量延迟中的叹号的意义:可以利用此规则取消文档中的英文叹号。
  15. echo  10、如果需要保留变量延迟中的英文叹号,请参照下面的例子。
  16. echo.
  17. echo      ^^!      
  18. echo      ——直接在叹号前面用两个转义符 ^^^^ ^^^^ 。
  19. echo.
  20. echo      ^^!手中有粮^^!  ^^^^^^^^ ^^!    ^^!心中不慌^^!     
  21. echo      ——在两对变量叹号中间添加一个带两个转义符的叹号。
  22. ::实际上是这样写的: echo  !手中有粮!  ^^!    !心中不慌!   
  23. ::中间那个带两个转义符的叹号才能正确显示出来。  
  24. echo.
  25. echo.
  26. echo      以上内容直接运行来看即可,后面的内容需要一边运行一边看代码。 下面是试验过程:
  27. echo.
  28. pause
  29. echo.
  30. echo.
  31. echo Hello!
  32. ::这样打出来的叹号会被忽略掉。
  33. echo !Hello!
  34. ::这样符号变量延迟的格式要求,没有显示。
  35. echo !Hello!   !Hello!  !Hello!
  36. ::以上同样符号要求,此时的叹号并非用作字符串,而是用作命令界定,没有显示。
  37. echo !Hello! Tom !Hello!    !Hello!
  38. ::我们在两个延迟变量中间加上一个Tom,结果它把这个Tom显示出来了。
  39. echo  OK? !Hello!  Tom  !Hello!  BeJing  !Hello! Nihao
  40. ::都显示出来了
  41. echo !Hello!  Tom!  !BeJing!    !Nihao!
  42. ::在Tom后面加了一个叹号,打乱了原来的规则,显示TomBeJingNihao。
  43. ::意味着第一对叹号是Hello,被忽略掉了。
  44. ::第二对是Tom后面,BeJing前面的两个叹号,它们同样被忽略掉了。
  45. ::第三对是BeJing后面,Nihao前面的两个叹号,它们同样被忽略掉了。
  46. ::最后一个叹号它并非显示字符串,在变量延迟下同样被忽略掉。
  47. ::这样,在三队叹号之间的字符串TomBeJingNihao就被显示出来了。
  48. echo   Hello    Tom^!
  49. ::取消字符的命令意义我们通常用 ^ ,而通常一个 ^ 是不够的。
  50. echo   Hello    Tom^^!
  51. ::必须用两个 ^ 才能将叹号转换为可显示的字符串。
  52. echo   Nihao^^!    Beijing^^!
  53. ::虽然存在两个叹号,但叹号已经被成功转义了,所以Beijing并未被忽略掉。
  54. echo   Nihao^!    Beijing^!
  55. ::可见转义符 ^ 在变量延迟里一样有效,不过它需要两个 ^ 来增强而已。
  56. echo.
  57. echo.
  58. echo       下面做练习:请猜猜下面的命令将显示什么?
  59. echo.
  60. echo       ^^!垃圾,你给我出来^^!
  61.                                                         ::终于正确显示了
  62. echo.
  63. pause
  64. echo.
  65. echo       ^^!SB!你藏里面做什么^^!
  66.                                                         ::只看见SB和它前面的!
  67. echo.
  68. pause
  69. echo.
  70. echo       ^^!上帝^!什么时候我也能彻底隐身^!没人能找到我的!!IP!!就好咯^^!
  71.                                                         ::只有“!上帝没人能找到我的”
  72. echo.
  73. pause
  74. echo.
  75. echo       !昨天!!我在马路边!!捡到!!!一分钱!!!真的吗?!是啊!!不骗你的!!!
  76. echo.
  77. pause
复制代码

TOP

回复 8# cjiabing


    楼主再总结下,在set 变量替换和 for ... ('findstr !...! ') 里的规则呗!感觉会要几万行

TOP

返回列表