Memory mapped file是使用正则表达式或对大型二进制文件进行操作的有效方法。
如果我有一个大文本文件(~1GB),是否可以使用编码感知映射文件?
像[\u1234-\u5678]
这样的正则表达式不适用于bytes
个对象,将模式转换为unicode也不起作用(因为"[\u1234-\u5678]".encode("utf-32")
例如无法正确理解范围)。
如果我使用str
将搜索模式从bytes
转换为.encode()
,搜索可能会有效,但它仍然有限,应该有一种更简单的方法,而不是整天解码和编码。
我尝试在io.TextIOWrapper
内用io.BufferedRandom
包装它,但无济于事:
AttributeError: 'mmap.mmap' object has no attribute 'seekable'
创建包装器(使用继承)并设置方法seekable
,readable
和writable
以返回True
也不起作用。
关于编码,可以假定固定长度编码,如utf-32
,代码点或utf-16
的较低BMP(如果它甚至可能仅涉及该部分)。
任何python版本都欢迎使用解决方案。
答案 0 :(得分:1)
如果不从头开始重新发明轮子(编写re
模块的所有新版本,mmap
模块等),或编写极其复杂的正则表达式,你就无法做到这一点。使用像真正的Unicode字符范围之类的东西的细节(你可以在三种不同的模式之间进行交替来制作[\u1234-\u5678]
,类似于(?:\x12[\x34-\xff]|[\x13-\x55].|\x56[\x00-\x78])
)。
基本上,re
模式仅适用于str
,或与bytes
类似的对象(您无法尝试使用memoryview
和强制转换,因为re
仍然将其视为字节,而不是更大的类型。)
对于简单搜索,您可以在编码用于搜索的字符串后尝试使用mmap.find
,但这仍然容易出现微妙的错误;对于UCS-2或UTF-32,您需要检查find
的返回值是否分别在两个或四个字节边界上对齐,以确保您没有误认为一个字符的结尾和开头下一个完全不同的角色。如果对齐测试失败,则必须使用最后一个返回值+ 1的start
偏移量重复搜索,直到您获得匹配或find
返回-1
为止。在一般情况下做这件事并不合理。