批字符转义

我相当精通Windows编写批处理脚本,但即使这些年来如何正确地转义字符拼图我。 当试图找出正确的方法来逃避sed使用的正则expression式是特别困难的。 有什么工具可以帮助我吗? 也许东西,让我粘贴在一个“正常”的string,它吐出了正确的逃避版本的string?

更新:我不愿举一个例子,因为我没有find如何转义一个特定string的答案。 我也没有寻找一个解决scheme,将适用于一个特定的应用程序。 我正在寻找一个工具,这将帮助我得到正确的逃生语法每一个string我需要逃脱,无论是什么工具可能会消耗它从命令行。

这就是说,我真正想要的是正则expression式

(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$ 

采取真正的正则expression式(即就BATCH而言未转义),并将其封装在某些sed语法中,如ssed "s@ --- Insert escaped regex here --- @http://psph/\1/\2@g" "%~1"并最终转义它…再次,有没有任何工具,可以帮助逃脱任何string在BATCH命令行上使用?

ps BATCH的转义语法有很多例外,我甚至可以解决一个好的备忘单。

这是经过作者的许可从页面批处理文件 – 转义 Rob van der Woude的Scripting Pages站点上的字符 。

TLDR

Windows(和DOS)批处理文件字符转义是复杂的 :

就像宇宙一样,如果任何人都完全了解Batch,那么语言将立即被一个无限的怪异和更复杂的版本所取代。 这显然至少发生过一次;)

百分号

%可以被转义为%% – “在引用双引号的字符串中可能并不总是需要[被转义],只要尝试”

通常,使用插入符号

这些字符“在引用双引号的字符串中可能并不总是需要[被转义],但它不会伤害到”:

  • ^
  • &
  • <
  • >
  • |

只有在FOR /F “主语”(即括号之间)中, '是”必须[要转义], 除非使用 backq

只有在FOR /F “subject”(即在括号之间)时, `是”才被要求[被转义], 如果使用 backq

这些字符是“仅在FOR /F ”主语“(即在括号之间), 即使在双引号字符串中必须[要转义]”:

  • ,
  • ;
  • =
  • (
  • )

使用延迟变量展开的双逃逸感叹号

! 必须逃脱^^! 延迟变量扩展处于活动状态时。

双重双引号find搜索模式

"""

findstr表达式模式中使用反斜杠

  • \
  • [
  • ]
  • "
  • .
  • *
  • ?

罗布在这个问题上进一步评论(通过电子邮件与我自己):

至于答案,恐怕混乱比原来的海报还要糟糕:括号内的转义要求也取决于字符串是否在代码块中!

我想一个自动化的工具可以在每个字符之前插入一个插入符号,然后将所有百分号加倍 – 如果字符串是双引号的,它仍然会失败!

此外,个别程序负责解析其命令行参数,因此,例如对于sedssed所需的一些转义可能是由批处理脚本中调用的特定程序造成的。

批处理的转义字符是^( ^ )。 如果您想在脚本中包含任何管道字符,则需要在字符前加上插入符:

 :: Won't work: @echo Syntax: MyCommand > [file] :: Will work: @echo Syntax: MyCommand ^> [file] 

您可以简单地使用外部文件作为sed的输入。

或者直接批量使用字符串,使用延迟扩展是个好主意。

 setlocal DisableDelayedExpansion set "regEx=s/^#*$/""/g" setlocal EnableDelayedExpansion sed !regEx! file.txt 

编辑:如何使用一批未经修改的字符串

这使用findstr从批处理直接获取字符串,并将其返回到结果变量。
所以你可以使用sed-string。

 @echo off setlocal REM SedString1#(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$ call :GetSEDString result SedString1 setLocal EnableDelayedExpansion echo the sedString is !result! sed !result! goto :eof :GetSEDString <resultVar> <searchName> :: Search the own batch file for <searchName> in a line with "REM <searchName>#" :: Return all after the "#" without any modification setLocal DisableDelayedExpansion for /f "usebackq tokens=* delims=" %%G in (`findstr /n /c:"REM %~2#" "%~f0"`) do ( set "str=%%G" ) setLocal EnableDelayedExpansion set "str=!str:*#=!" for /F "delims=" %%A in ("!str!") DO ( endlocal endlocal set "%~1=%%A" goto :eof ) goto :eof