2

一个小问题一直困扰着我几天。我正在尝试从 *.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 的开头。但是还没有找到方法来做到这一点。可能吗?
有没有什么办法,将我的正则表达式结果复制到一个变量中?
我希望错过了标准命令外壳中正则表达式的一些神奇命令。

4

1 回答 1

1

使用纯批处理几乎不可能完成您想要的操作,因为您的二进制文件可能包含 nul 字节并且批处理无法处理 null 字节。但是使用 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/batch),可以在 XP 以后的任何 Windows 机器上本地运行。完整的文档嵌入在脚本中。

下面简单列出了在文件中找到的值。请注意,该/M选项是必需的,因为 exe 中可能存在空字节。

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"
于 2012-11-09T18:28:15.293 回答