Board logo

标题: [文本处理] [分享]批处理区分引号内外,转义特殊字符 [打印本页]

作者: CrLf    时间: 2012-1-30 16:50     标题: [分享]批处理区分引号内外,转义特殊字符

记得初中的时候有节数学课,老师叫同学从有 10 个球的袋子里取 8 个,那位同学却只拿了两个球。
老师很惊讶:“还有六个呢?”
同学说:“那八个都在袋子里。”
早已记不清这堂课究竟是讲什么的了,但唯独对这件事记忆犹新。

在批处理中,我们可以用相同的办法,把字符串中的特殊字符简单转义,并且能区别对待引号对内外的特殊字符。

原理:
  1. ::str 原始值为: "&"&
  2. set "str=!str:&=^&!"
  3. ::str 的值变为: "^&"^&
  4. set "str="^&"^&"
  5. ::str 的值变为: "&"^&
复制代码
for 未开启变量延迟的环境:
  1. :testg"j!l>!k(s)"d&vj|l!fs^d
  2. @echo off&setlocal enabledelayedexpansion
  3. set /p str=<%0
  4. echo    原始字符串:!str!
  5. :: 获取原始字符串
  6. for %%a in (^^ ^& ^| ^( ^) ^< ^>) do set "str=!str:%%a=^%%a!"
  7. echo  转义特殊字符:!str!
  8. :: 为所有特殊字符前缀一个 ^ 转义符。
  9. setlocal disabledelayedexpansion
  10. ::关闭变量延迟
  11. set "str=%str%"
  12. :: 这一句是核心,用于将引号对之内多余的 ^ 消除,原理详见前文
  13. echo      最终效果:%str%
  14. :: 因为引号对之外的特殊字符都被加上了 ^,所以此时能正常输出所有内容
  15. pause
复制代码
for 开启了变量延迟的环境:
  1. :testg"j!l>!k(s)"d&vj|l!fs^d
  2. @echo off&setlocal enabledelayedexpansion
  3. set /p str=<%0
  4. echo    原始字符串:!str!
  5. set "str=!str:^=^^!"
  6. :: 特殊字符 ^ 需翻倍
  7. for %%a in (^^ ^& ^| ^( ^) ^< ^>) do set "str=!str:%%a=^^^%%a!"
  8. echo  转义特殊字符:!str!
  9. :: 因为在开启变量延迟的情况下,一条语句中如果含有 !,一定会产生一次额外的转义(以便判断 ! 符号的用途),所以将所有 ^ 翻三倍(2的0次方 + 2的1次方)
  10. echo  转义特殊字符:!str!
  11. set "str=!空变量!%str:!=^^^^^^^!%"
  12. :: 核心语句,将 ! 前缀七个 ^ (2的0次方 + 2的1次方 + 2的2次方),并将引号对之内多余的 ^ 消除
  13. :: 之所以要加个 !空变量!,是防止中 str 不存在 ! 字符时无法触发额外的转义行为。
  14. echo    转义感叹号:!str!
  15. echo      最终效果:%str%
  16. :: 到此证明转义成功~
  17. pause
复制代码

作者: amwfjhh    时间: 2014-12-3 22:49

这篇可以放到批处理教程里面去了。
作者: CrLf    时间: 2014-12-3 23:34

发现一个错误,顺便修改下...
作者: amwfjhh    时间: 2014-12-4 12:31

把%与=这两个字符再添进去吧。就更完美了。
作者: tiandyoin    时间: 2023-2-28 11:50

回复 3# CrLf


    什么错误。




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2