批处理文件用转义的感叹号替换感叹号
Posted
技术标签:
【中文标题】批处理文件用转义的感叹号替换感叹号【英文标题】:Batch File Replace Exclamation Mark with Escaped Exclamation Mark 【发布时间】:2012-11-01 14:04:06 【问题描述】:我正在处理一个将数据作为变量获取的批处理文件,并且在该变量中它有一个感叹号。
我想要做的是将必要的转义字符添加到变量中。
"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 变量放在循环中,它错误而不是真实值我只看到我上面使用的实际替换命令。
【问题讨论】:
是为了个人娱乐(“看看我能在 CMD 中做什么”)还是你需要它? javascript 会更容易做到这一点。您可以在所有最新(我认为是 2000+)版本的 Windows 上使用cscript my.js
运行脚本。旁注:可能有更好的方法来执行您尝试通过搜索和替换实现的操作......
基本上我正在尝试对从 omdbapi.com 检索到的 json 数据进行一些处理。这是出于教育和实用目的,当然,看看我是否可以使用 wget 通过 json 获取数据。我可以得到数据,我只想正确解析它。到目前为止,这很困难,但可行。
您在第一次扩展 set json=%json:~1,-1%
时丢失了数据。你如何将文本放入变量中?通过 FOR/F 循环?
rem 捕获文本文件结果到变量集 /p json= 如果您启用延迟扩展,则不应使用带有特殊字符的百分比扩展。 如果您使用延迟扩展,则不会遇到感叹号或其他字符的问题。
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
)
【讨论】:
引号内的感叹号是正确的。我正在尝试解析一个 json 脚本,这只是 json 字符串的一个标记。每个都以 "VariableName":"Value" 开头,我正在尝试执行一个基于冒号分隔的循环,但由于未转义的感叹号,进入循环的值会出错。 我的目标是循环遍历每个变量/值组合,然后使用令牌内的变量名称创建一个批处理变量,然后将值分配给它。它需要具有返回文本的完整值。并且值可能会根据我查询此网络源的内容而改变。是否存在将特殊字符替换为转义字符的现有函数? 正如我所说,您可以逃脱它们,但这没有任何意义。使用延迟扩展处理任何内容 问题是当变量被放入循环时出错了。 现在的主要问题是转义函数,然后将其放入循环字符串中。【参考方案2】:我不相信你真的需要逃离!
。可以这样做,但正如 jeb 试图解释的那样,它可能会变得复杂。
根据您提供的代码,在我看来您不了解延迟扩展的作用。我建议您在命令提示符下键入 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
【讨论】:
谢谢,这对我很有帮助。我已将此作为函数调用添加到我的主批处理文件中,希望这将帮助我自动化一些视频重命名功能。【参考方案3】:您可以使用 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
【讨论】:
+1。这是作弊 :) 当 CMD 是(我相信)图灵完成时使用实际语言......【参考方案4】:jeb 和 dbenham 已经完全回答了这个问题,所以这有点离题...
我使用了一个小技巧来避免记住必须插入多少个插入符号才能在不同情况下使用感叹号的麻烦。我定义了一个禁用延迟扩展的变量,并为其分配了一个感叹号(我称之为bang)。然后我启用延迟扩展并将其用作 !bang!。这样,这个值总是会显示为感叹号,而且很容易写...
@echo off
setlocal DisableDelayedExpansion
set bang=!
setlocal EnableDelayedExpansion
echo Yes, it works!bang!
安东尼奥
【讨论】:
以上是关于批处理文件用转义的感叹号替换感叹号的主要内容,如果未能解决你的问题,请参考以下文章