Python mmap对象抱怨Python 3.5.2上的字符串模式(不在Python 2.6.6中)

时间:2016-08-17 12:26:54

标签: python regex performance mmap

我有以下代码:

def grep(pattern, file_path):
    with io.open(file_path, "r", encoding="utf-8") as f:
        file_size = os.path.getsize(file_path)
        mm        = mmap.mmap(f.fileno(), file_size, access=mmap.ACCESS_READ)
        return re.search(pattern, mm)

使用Python 2.6.6,我可以使用r'approved="no"'模式 使用Python 3.5.2,我必须使用b'approved="no"'模式。否则,我得到TypeError: cannot use a string pattern on a bytes-like object

有没有办法在Python 3.5.2中使用原始字符串模式?我有使用相同的原始字符串模式的代码,我使用mmap传递给此函数,所以我想重用这些模式。

我已经尝试将mmap对象读入字符串,但这会大大降低Windows上的性能(在Linux上没那么多)

data = str(mm.read(file_size))
return re.search(pattern, data)

结果

工作集:405个Xliff文件,共计3,860,117行 用Python (time.time() - start_time)测量时间 将mmap对象读入字符串:29s
直接在正则表达式中使用二进制模式和mmap对象:3s

2 个答案:

答案 0 :(得分:2)

最简单的方法可能就是编码为utf-8:

def grep(pattern, file_path):
    pattern =  pattern.encode("utf-8")
    with io.open(file_path, "r", encoding="utf-8") as f:
        file_size = os.path.getsize(file_path)
        mm = mmap.mmap(f.fileno(), file_size, access=mmap.ACCESS_READ)
        return re.search(pattern, mm)

它会在python3上给你字节,并且我评论说使用python2在str和字节之间没有区别。

答案 1 :(得分:1)

bytes也可以是原始文字。如果您的模式仅与mmap(或其他bytes类似的东西一起使用),您可以使用br'approved="no"',这在2.6及更高版本上受支持就好了{{1通常在Py2.x上是冗余的,但它对b转换器意味着什么,并将撤消2to3对该特定文字的影响。

可悲的是,在Py2.x(和Py3.2及以下版本)上,前缀顺序很重要,from __future__ import unicode_literals很好,br'approved="no"'是语法错误。在Py 3.3及更高版本中,任何一个订单都被接受(我自己更喜欢后者,因为它在我的头脑中自然地读取"原始字节",相对于更笨拙"字节raw",但便携性优先。)

显然,如果您的其他用途是严格文本(Py2 rb'approved="no"',Py3 unicode),Padraic的编码答案(或存储为str并在其他地方解码places)是避免存储每个模式的两个副本的唯一选择。