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

时间:2012-11-13 04:48:16

标签: batch-file windows-xp replace

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

我要做的是将必要的转义字符添加到变量中。

"Title":"Turk 182!"

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

setlocal EnableDelayedExpansion
rem replace ! with ^^!
set var=%var:!=^^!!%

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

我正在尝试用转义版本替换所有的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

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

4 个答案:

答案 0 :(得分: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_

这是输出

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

答案 1 :(得分:5)

如果启用延迟扩展,则不应将百分比扩展与特殊字符一起使用 如果您使用的是延迟扩展,则不会出现感叹号或其他字符的问题。

set myTitle="Turk 182!"
setlocal EnableDelayedExpansion
echo Title=!myTitle!

你可以替换感叹号,但是你需要多个插入符号,并且计数取决于许多事情。

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

作为小样本,为什么百分比扩张不是最佳选择

@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%

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

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

答案 2 :(得分:1)

您可以使用PowerShell:

$json=@"
  {"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"}
"@

add-type -assembly system.web.extensions
$jserial = new-Object Web.Script.Serialization.JavaScriptSerializer
$jserial.DeserializeObject($json)

Key                                                         Value
---                                                         -----
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 ..
Poster                                                      http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl..
imdbRating                                                  5.7
imdbVotes                                                   2,360
imdbID                                                      tt0090217
Response                                                    True

或使用PowerShell v3:

PS III> $json | ConvertFrom-JSON

Key                                                         Value
---                                                         -----
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 ..
Poster                                                      http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl..
imdbRating                                                  5.7
imdbVotes                                                   2,360
imdbID                                                      tt0090217
Response 

答案 3 :(得分:1)

jeb和dbenham已经完全回答了这个问题,所以这有点偏离主题......

我使用了一个小技巧,以避免记住为了在不同情况下使用感叹号必须插入多少插入符号的麻烦。我定义了一个禁用延迟扩展的变量,并为其分配一个感叹号(我称之为 bang )。然后我启用延迟扩展并将其用作!bang!。这样,此值将始终显示为感叹号,并且很容易编写...

@echo off
setlocal DisableDelayedExpansion
set bang=!
setlocal EnableDelayedExpansion
echo Yes, it works!bang!

安东尼奥