我有一个混合二进制数据和文本数据的文件。我想通过正则表达式解析它,但出现此错误:
TypeError: can't use a string pattern on a bytes-like object
我猜测该消息意味着 Python 不想解析二进制文件。 我正在使用
"rb"
标志打开文件。
如何在Python中使用正则表达式解析二进制文件?
编辑:我正在使用Python 3.2.0
我认为你使用的是Python 3。
1.以二进制模式打开文件简单但微妙。唯一的区别 以文本模式打开它是 模式参数包含 'b' 性格。
........
4. 不过,这里有一个区别:二进制流对象没有编码 属性。这是有道理的,对吧? 您正在读取(或写入)字节,而不是 字符串,所以没有转换 Python 来做。
然后,在 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 可以帮助你。
和
4.6。字符串与字节# 字节就是字节;字符是一种抽象。 Unicode 的不可变序列 字符称为字符串。一个 不可变序列 0 到 255 之间的数字称为 字节对象。
....
1.要定义字节对象,请使用 b' '“字节文字”语法。每个字节 字节文字内可以是 ASCII 字符或编码 从 \x00 到 \xff 的十六进制数 (0–255)。
所以你将定义你的正则表达式如下
pat = re.compile(b'[a-f]+\d+')
而不是
pat = re.compile('[a-f]+\d+')
更多解释在这里:
在您的
re.compile
中,您需要使用 bytes
对象,由首字母 b
表示:
r = re.compile(b"(This)")
这是 Python 3 对字符串和字节之间差异的挑剔。
这是我如何在我自己定制的
egrep
“克隆”中做到这一点:
import sys
import re
import posix
try:
Pattern = re.compile(bytes(sys.argv[1], sys.getdefaultencoding()))
except IndexError:
print('Usage:\n\t%s pattern file1.zip [file2.zip ...]', sys.argv[0])
sys.exit(posix.EX_USAGE)
except re.error as e:
print('Invalid search pattern "%s": %s' % (sys.argv[1], e))
sys.exit(posix.EX_USAGE)
sys.getdefaultencoding())
决定第一个命令行参数的编码。知道编码后,您可以将字符串转换为bytes。然后,给定字节(而不是字符串)re.compile()
将生成适合检查字节的正则表达式。
这对我来说适用于 python 2.6
>>> import re
>>> r = re.compile(".*(ELF).*")
>>> f = open("/bin/ls")
>>> x = f.readline()
>>> r.match(x).groups()
('ELF',)