正则表达式解析二进制文件?

Posted

技术标签:

【中文标题】正则表达式解析二进制文件?【英文标题】:Regular expression parsing a binary file? 【发布时间】:2011-08-02 21:40:47 【问题描述】:

我有一个混合了二进制数据和文本数据的文件。我想通过正则表达式对其进行解析,但出现此错误:

TypeError: can't use a string pattern on a bytes-like object

我猜这个消息意味着 Python 不想解析二进制文件。 我打开带有"rb" 标志的文件。

如何在 Python 中使用

编辑:我使用的是 Python 3.2.0

【问题讨论】:

我从对字节类对象的引用中猜测您正在使用 Python 3,对吗? 【参考方案1】:

我认为你使用的是 Python 3。

1.以二进制模式打开文件简单但微妙。唯一的区别 从以文本模式打开它是 mode参数包含一个'b' 字符。

........

4.这里有一个区别:二进制流对象没有编码 属性。这是有道理的,对吧? 您正在读取(或写入)字节,而不是 字符串,所以没有转换 Python 来做。

http://www.diveintopython3.net/files.html#read

然后,在 Python 3 中,由于来自文件的二进制流是字节流,因此分析来自文件的流的正则表达式必须使用字节序列而不是字符序列来定义。

在 Python 2 中,字符串是一个数组 字符编码为的字节 单独跟踪。如果你想要 Python 2 来跟踪 字符编码,你必须使用 Unicode 字符串 (u'') 代替。但在 Python 3,字符串总是什么 Python 2 称为 Unicode 字符串—— 即 Unicode 数组 字符(可能不同的字节 长度)。

http://www.diveintopython3.net/case-study-porting-chardet-to-python-3.html

在 Python 3 中,所有字符串都是序列 Unicode 字符。没有 诸如 Python 字符串编码之类的东西 UTF-8 或 Python 字符串编码 作为 CP-1252。 “这个字符串是 UTF-8 吗?”是 一个无效的问题。 UTF-8 是一种 将字符编码为一个序列 字节。如果你想取一个字符串 并把它变成一个字节序列 在特定的字符编码中, Python 3 可以帮助你。

http://www.diveintopython3.net/strings.html#boring-stuff

4.6。字符串与字节#字节是字节;字符是一种抽象。 不可变的 Unicode 序列 字符称为字符串。一个 不可变序列 介于 0 和 255 之间的数字称为 字节对象。

....

1.要定义字节对象,请使用 b' ' “字节文字”语法。每个字节 在字节文字内可以是 ASCII 字符或编码的 从 \x00 到 \xff 的十六进制数 (0–255)。

http://www.diveintopython3.net/strings.html#boring-stuff

所以你将定义你的正则表达式如下

pat = re.compile(b'[a-f]+\d+')

而不是像

pat = re.compile('[a-f]+\d+')

这里有更多解释:

15.6.4. Can’t use a string pattern on a bytes-like object

【讨论】:

@John Machin 请问您是什么意思? 是否有任何合法的正则表达式存在混淆 \x00 的正则表达式或表示二进制数据的任何有效替代方案的风险?我的 IDE 抱怨我的字节字符串中有一个无效的转义序列 \d。 为什么人们做的例子总是使用硬编码的字符串?如果将正则表达式模式从文本文件读取为纯字符串,而没有解释如何将其转换为 (compatible) 二进制字符串,这根本没有帮助。 ?【参考方案2】:

在您的re.compile 中,您需要使用bytes 对象,由初始b 表示:

r = re.compile(b"(This)")

这是 Python 3 对字符串和字节之间的区别的挑剔。

【讨论】:

如果模式不是在脚本中硬编码而是从文本文件中读取到字符串变量中怎么办?如何将其转换为 (compatible) 字节字符串? ?【参考方案3】:

这对我适用于 python 2.6

>>> import re
>>> r = re.compile(".*(ELF).*")
>>> f = open("/bin/ls")
>>> x = f.readline()
>>> r.match(x).groups()
('ELF',)

【讨论】:

此代码 import re; r = re.compile("(This)"); f = open(r"C:\WINDOWS\system32\mspaint.exe", "rb"); x = f.readline(); r.match(x).groups() 返回与我的原始帖子相同的错误

以上是关于正则表达式解析二进制文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用正则表达式解析日志文件

解析大文件时避免正则表达式回溯

通过正则表达式实现简单xml文件解析

在 C# 中使用正则表达式从完整路径解析文件名

easyui界面正则表达式不解析怎么办?

使用正则表达式从文本文件中解析 [重复]