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

40 投票
3 回答
57480 浏览
提问于 2025-04-16 15:29

我有一个文件,里面混合了二进制数据和文本数据。我想用正则表达式来解析它,但出现了这个错误:

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

我猜这个错误信息的意思是,Python 不想解析二进制文件。我是用 "rb" 的方式打开这个文件的。

那我该怎么用正则表达式在 Python 中解析二进制文件呢?

补充:我使用的是 Python 3.2.0

3 个回答

-3

这段代码在我这里的 Python 2.6 版本上运行得很好。

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

在你的 re.compile 里,你需要使用一个 bytes 对象,前面要加一个 b

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

这是因为 Python 3 对字符串和字节的区别很严格。

39

我觉得你在用 Python 3。

1. 以二进制模式打开文件其实很简单,但有点细微的区别。和以文本模式打开文件的唯一不同就是模式参数里多了一个'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 字符的序列没有什么叫做用 UTF-8 编码的 Python 字符串,或者用 CP-1252 编码的 Python 字符串。“这个字符串是 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. 不能在类似字节的对象上使用字符串模式

撰写回答