批处理文件用转义的感叹号替换感叹号

cro*_*lum 5 windows-xp replace batch-file

我正在处理一个将数据作为变量获取的批处理文件,并且在该变量中它有一个感叹号.

我想要做的是为变量添加必要的转义字符.

"Title":"Turk 182!"
Run Code Online (Sandbox Code Playgroud)

以上是我正在使用的数据的示例.

setlocal EnableDelayedExpansion
rem replace ! with ^^!
set var=%var:!=^^!!%
Run Code Online (Sandbox Code Playgroud)

但我不确定这是正确的语法,因为如果它也被用作搜索和替换的一部分,我怎么能逃脱一个咒语?

我试图用转义版本替换所有的esclamation标记,以便它可以显示和使用.

顺便说一下,批处理中是否有任何现有的功能会删除并允许转义所有特殊字符?

这里有更多代码可以帮助解释我在做什么.

{"Title":"Turk 182!","Year":"1985","Rated":"PG-13","Released":"15 Feb 1985","Runtime":"1 h 42 min","Genre":"Action, Comedy, Drama","Director":"Bob Clark","Writer":"Denis Hamill, James Gregory Kingston","Actors":"Timothy Hutton, Robert Urich, Kim Cattrall, Robert Culp","Plot":"Jimmy Lynch is angry because his older brother, who was injured as a result of an off duty fire rescue...","Poster":"http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl5BanBnXkFtZTcwNjYwNjgyMQ@@._V1_SX300.jpg","imdbRating":"5.7","imdbVotes":"2,360","imdbID":"tt0090217","Response":"True"}

rem removes starting and ending brackets
set json=%json:~1,-1%
setlocal EnableDelayedExpansion
rem replace "," with linebreak
set json=!json:","="#"!
setlocal EnableDelayedExpansion
rem replace ! with ^^!
set json=%json:!=^^!!%

setlocal DisableDelayedExpansion
echo %json%
echo.
exit /b
Run Code Online (Sandbox Code Playgroud)

然后我将json变量放在循环中并且它出错而不是真值我只看到我上面使用的实际替换命令.

dbe*_*ham 6

我不相信你真的需要逃避!.这是可能的,但正如杰布试图解释的那样,它可能会变得复杂.

根据您提供的代码,我认为您不了解延迟扩展的作用.我建议你HELP SET从命令提示符输入并阅读文档.延迟扩展的描述开始大约有一半的下划线"最后,支持延迟环境变量扩展..."

延迟扩张还有其他主要好处.最大的优点之一是,当您使用延迟扩展时,您永远不必担心转义任何特殊字符.在使用正常扩展时转义字符是一种痛苦,在获得经验之前可能会非常混乱.(这确实是合乎逻辑且可预测的,但在你理解之前,它看起来像是胡言乱语)

延迟扩展的最大问题是当数据包含时,它不能与FOR循环一起使用!.这是因为延迟扩展发生在FOR变量展开之后,因此包含的值!将被破坏.在我下面的json解析器中,我在循环内切换延迟扩展以避免该问题.

我对json知之甚少,所以我的解决方案可能是天真的(不完整的).但这是一个简单的json解析器,它可以处理您提供的数据.我把你的json字符串放在一个名为"test.txt"的文件中

@echo off
setlocal disableDelayedExpansion
setlocal enableDelayedExpansion

::Read the json string from a file
<test.txt set /p "json="

::Define LF variable to contain a linefeed
set LF=^


::The above 2 blank lines are critical - DO NOT REMOVE

::Strip the enclosing braces
set "json=!json:~1,-1!"

::Substitute a linefeed for ","
for %%A in ("!LF!") do set "json=!json:","=%%~A!"

::Substitute = for ":"
set "json=!json:":"==!"

::Remove remaining "
set "json=!json:"=!"

::Loop through the data, creating variables of the form var_name=value
for /f "delims=" %%A in ("!json!") do (

  REM If delayed expansion is enabled then endlocal to get back to disabled state
  if "!!" equ "" endlocal

  REM Create the variable
  set "var_%%A"
)

::Display the results - list all variables that begin with var_
set var_
Run Code Online (Sandbox Code Playgroud)

这是输出

var_Actors=Timothy Hutton, Robert Urich, Kim Cattrall, Robert Culp
var_Director=Bob Clark
var_Genre=Action, Comedy, Drama
var_imdbID=tt0090217
var_imdbRating=5.7
var_imdbVotes=2,360
var_Plot=Jimmy Lynch is angry because his older brother, who was injured as a result of an off duty fire rescue...
var_Poster=http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl5BanBnXkFtZTcwNjYwNjgyMQ@@._V1_SX300.jpg
var_Rated=PG-13
var_Released=15 Feb 1985
var_Response=True
var_Runtime=1 h 42 min
var_Title=Turk 182!
var_Writer=Denis Hamill, James Gregory Kingston
var_Year=1985
Run Code Online (Sandbox Code Playgroud)


jeb*_*jeb 5

如果启用了延迟扩展,则不应使用带有特殊字符的百分比扩展。
如果使用延迟扩展,则不会出现感叹号或其他字符的问题。

set myTitle="Turk 182!"
setlocal EnableDelayedExpansion
echo Title=!myTitle!
Run Code Online (Sandbox Code Playgroud)

您可以替换感叹号,但是您需要使用多个尖号,并且计数取决于许多因素。

  • 引号内是否有感叹号?
  • 您是直接回显它还是要从一个变量复制到另一个变量然后进行回显?
  • 如何将其与另一个值进行比较。

作为一个小样本,为什么膨胀百分比不是最佳选择

@echo off
set test1=An exclamation mark^^^^!
setlocal EnableDelayedExpansion
set test2=An exclamation mark^^^^^^^^^^!
set "test3=An exclamation mark^^^^^!"
set test4a=An exclamation mark^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
set test4b=%test4a%!
echo %test1%
echo %test2%
echo %test3%
echo %test4b%
Run Code Online (Sandbox Code Playgroud)

如果您想以安全的方式从文件中读取文本,则可以使用延迟切换技术。

setlocal DisableDelayedExpansion
for /F "delims=" %%a in (myFile.txt) DO (
  set "line=%%a"
  setlocal EnableDelayedExpansion
  echo !line!
  endlocal
)
Run Code Online (Sandbox Code Playgroud)