我希望使用re
模块与流,但不一定是文件流,以最小的开发成本。在
对于文件流,有一个mmap
模块,它能够模拟字符串,因此可以与re
一起自由使用。在
现在我想知道mmap
如何设计一个re
可以进一步重用的对象。如果我只传递任何内容,re
保护自己不受与TypeError: expected string or bytes-like object
不兼容的对象的使用。所以我想我应该创建一个从string
或bytes
派生的类,并覆盖一些方法,比如__getitem__
等(这很直观地符合Python的duck类型哲学),并使它们与我的原始流交互。然而,这似乎根本不起作用-我的覆盖被完全忽略了。在
有没有可能在纯Python中创建这样一个“lazy”string
,而没有C扩展?如果是,怎么办?在
忽略其他解决方案的背景:
mmap
(流内容不是文件)演示bytes
抵抗修改的示例代码:
class FancyWrapper(bytes):
def __init__(self, base_str):
pass #super() isn't called and yet the code below finds abc, aaa and bbb
print(re.findall(b'[abc]{3}', FancyWrapper(b'abc aaa bbb def')))
嗯,我发现这不可能,目前不行。在
Python的
re
模块对字符串进行内部操作,因为它扫描的是一个普通的C缓冲区,它需要接收到的对象来满足这些属性:因此,即使我们设法使}不同的东西工作,我们也必须使用类似
re
与bytes
或{mmap
的行为,即将我们的内容提供者模拟为系统内存中的线性区域。但是
mmap
机制只对文件有效,事实上,即使这样也很有限。例如,如果一个人试图写入一个大文件,就不能mmap
它,就像this answer。regex
模块,也不能容纳string
和{完整性方面:这是否意味着我们已经完蛋了,不能用
re
来浏览大量动态内容?不一定。有一种方法可以做到,如果我们允许限制最大匹配大小。该解决方案的灵感来自cfi的注释,并将其扩展到二进制文件。在通过使用两倍于最大匹配大小的缓冲区来实现这一点?假设用户搜索
A{3}
,并且最大匹配大小设置为3。如果我们只读取max match size字节到扫描缓冲区,并且当前x的数据包含AABBBA
:AAB
。不匹配。在BBA
。还是没有对手。在这显然很糟糕,简单的解决方案是读取两倍于我们跳过的字节数,以确保扫描缓冲区尾部附近的异常得到解决。在
注意,在扫描缓冲区内的第一个匹配上的短路被认为是为了防止其他异常,例如缓冲区扫描不足。可能会对其进行调整,以最小化包含多个匹配项的扫描缓冲区的读取,但我希望避免使事情进一步复杂化。在
这可能不是最具性能的算法,但对于我的用例来说已经足够好了,所以我将它留在这里。在
相关问题 更多 >
编程相关推荐