返回Lua中字符串的偏移量

我正在尝试在相当大的文件中搜索特定的字符串并返回其偏移量。我是 Lua 新手,我的当前方法看起来像这样:

linenumber = 0
for line in io.lines(filepath) do
result=string.find(line,"ABC",1)
linenumber = linenumber+1

if result ~= nil then
offset=linenumber*4096+result
io.close
end
end

我意识到这种方式相当原始,肯定很慢。我怎样才能更有效地完成这个任务?

提前感谢。

原文链接 https://stackoverflow.com/questions/8907949

点赞
stackoverflow用户107090
stackoverflow用户107090

除非你的行都具有相同的长度(4096),否则我不认为你的代码能够运行。

与其使用io.lines,读取块时使用io.read(4096)。除此之外,你的代码可以不变,只是需要处理字符串不完全在块内的情况。如果文件由行组成,则《Lua编程》中提到的一个技巧是使用io.read(4096,"*l")读取以行结束的块。然后你不必担心字符串没有完全包含在块内,但需要调整偏移量计算以包括块的长度,而不仅仅是4096。

2012-01-18 10:00:20
stackoverflow用户513763
stackoverflow用户513763

如果文件大小不是很大,你可以在内存空间允许的情况下直接将整个文件读入内存并使用 string.find 函数进行搜索,速度会更快。否则,可以分块搜索文件。

你的方法并不算糟糕。我建议采用重叠的块加载文件。这样做可以避免模式正好被拆分在两个块之间而被忽略,例如:

".... ...A BC.. ...."

我的实现方法如下:

size=4096 -- 注意:size 应该比 pat 的长度大才能正常工作。
pat="ABC"
overlap=#pat
fh=io.open(filepath,'rb') -- 在 Windows 上,不要忘记使用 b 模式
block=fh:read(size+overlap)
n=0
while block do
    block_offset=block:find(pat)
    if block_offset then
        print(block_offset)
        offset=block_offset+size*n
        break
    end
    fh:seek('cur',-overlap)
    cur=fh:seek'cur'
    block=fh:read(size+overlap)
    n=n+1
end

if offset then
    print('found pattern at', offset, 'after reading',n,'blocks')
else
    print('did not find pattern')
end

如果你的文件真正包含行信息,你也可以使用这里所解释的技巧。这本书的一节介绍了一些在读取文件时需要注意的性能问题。

2012-01-18 10:38:14