在Windows批处理中从二进制文件中提取RegEx字符串

时间:2012-11-09 16:05:15

标签: for-loop batch-file binary cmd findstr

一个小小的问题一直困扰着我几天。我正在尝试使用regexp从* .exe二进制文件中提取一个字符串,将文本如“1.01.01.00T123”提取到环境变量中以供进一步使用。
我找到了带

的字符串
findstr /i [0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][T][0-9][0-9][0-9] name.exe>outp.bin

现在它是我的字符串,有点小二进制,可能是200字节。然后我试图在“for / f”中使用findstr的输出,但是我应该为二进制使用什么分隔符,没有任何保证。即使是点和空白也可以来去 类似的东西:

for /f "tokens=1,2,3,4* delims=^." %%a in ('findstr /i [0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]T[0-9][0-9][0-9] name.exe') do (
echo %%a
echo %%b
echo %%c
echo %%d
)

它仅在中途工作 - 第一部分太长,最后一部分“xxTxxx”不是此定义的标记。除了点也可以发生在二进制内部,而不仅仅是在我的字符串中 我想通过切断第一个字节来缩短循环中的outp.bin,然后检查我的字符串是否在outp.bin的开头。但还是没有办法做到这一点。有可能吗?
有没有办法,将我的正则表达式结果复制到变量中就不那么复杂了? 我希望错过标准命令shell中regexp的一些魔术命令。

1 个答案:

答案 0 :(得分:1)

使用纯批处理几乎不可能做到你想要的,因为你的二进制文件可能包含nul字节而批处理不能处理空字节。但是使用VBS或JScript和正则表达式可以很容易地解决问题。

这是一个非常粗略的VBS解决方案,有很大的改进空间。但它确实有效。

<强> findStr.vbs

Set myRegExp = New RegExp
myRegExp.IgnoreCase = True
myRegExp.Global = True
myRegExp.Pattern = "\d\.\d\d\.\d\d\.\d\dT\d\d\d"
Set matches = myRegExp.Execute(WScript.StdIn.ReadAll())
For Each match In matches
  WScript.StdOut.WriteLine(match.value)
Next

使用CSCRIPT调用脚本并将输入重定向到exe文件。

<name.exe cscript //nologo findStr.vbs

您可以使用批处理通过FOR / F处理结果。

for /f "delims=" %%A in ('^<name.exe cscript //nologo findStr.vbs') do echo %%A


更新 - 2015-08-26

您可以使用JREPL.BAT轻松解决这个问题 - 一个基于纯脚本的正则表达式处理能力(混合JScript /批处理),可以在任何Windows机器上从XP开始本地运行。完整的文档嵌入在脚本中。

以下简单列出文件中的值。请注意,由于exe中可能存在空字节,因此需要/M选项。

call jrepl "\d\.\d\d\.\d\d\.\d\dT\d\d\d" $0 /jmatch /m /f name.exe

捕获变量中的值(如果有多次出现,则捕获最后一个值):

for %%A in (
  'jrepl "\d\.\d\d\.\d\d\.\d\dT\d\d\d" $0 /jmatch /m /f name.exe'
) do set "str=%%A"