5

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

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

"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

4 回答 4

6

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

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
)
于 2012-11-13T06:21:02.137 回答
6

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

根据您提供的代码,在我看来您不了解延迟扩展的作用。我建议您HELP SET从命令提示符键入并阅读文档。延迟扩展的描述从大约一半开始,内容为“最后,支持延迟的环境变量扩展......”

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

延迟扩展的最大问题是当数据包含!. 那是因为延迟扩展发生在 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
于 2012-11-13T12:40:35.633 回答
1

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

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

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

安东尼奥

于 2012-11-13T20:25:06.627 回答
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 
于 2012-11-13T16:36:18.447 回答