String 返回带有lua的字符串的偏移量

String 返回带有lua的字符串的偏移量,string,lua,find,return,offset,String,Lua,Find,Return,Offset,我试图在相当大的文件中搜索某个字符串并返回其偏移量。我是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 size=4096 -- note, size sho

我试图在相当大的文件中搜索某个字符串并返回其偏移量。我是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
size=4096 -- note, size should be bigger than the length of pat to work.
pat="ABC"
overlap=#pat
fh=io.open(filepath,'rb') -- On windows, do NOT forget the 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
我意识到这种方式相当原始,而且肯定很慢。我怎样才能更有效地做到这一点


提前谢谢。

除非您的代码行具有相同的长度(4096),否则我看不出您的代码是如何工作的


不要使用
io.line
,而是使用
io.read(4096)
读取块。代码的其余部分可以按原样使用,只是需要处理字符串未完全位于块中的情况。如果文件是由行组成的,那么在Lua编程中提到的一个技巧是执行
io.read(4096,“*l”)
,读取以行边界结束的块。然后,您不必担心块中的字符串不完整,但需要调整偏移量计算以包括块的长度,而不仅仅是4096。

如果文件不是太大,并且您可以节省内存,则只需在整个文件中插入字符串并使用
string.find
会更快。如果没有,则可以按块搜索文件

你的方法也没那么糟糕。我建议将文件加载到重叠块中。重叠可避免图案仅在块之间分割而不被注意,如:

".... ...A BC.. ...."
我的实现如下所示:

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
size=4096 -- note, size should be bigger than the length of pat to work.
pat="ABC"
overlap=#pat
fh=io.open(filepath,'rb') -- On windows, do NOT forget the 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

如果文件中确实有行,也可以使用上面介绍的技巧。在Lua的编程中,一本书解释了阅读文件时的一些性能注意事项。

感谢您的快速回复!我用process monitor分析了io.lines的读取行为,它显示文件是以4096字节的块读取的,因此我假设这是io.lines的标准值。你的解决方案让我明白了。再次感谢!非常感谢你的例子!它就像一个符咒。我通过第21.1节学习。在发布我的问题之前,我读了lua代码手册,但是我错过了21.2.1,所以谢谢你的提示!我还不熟悉“#”符号的概念。显然,您使用它来创建重叠,但是lua代码手册中是否有一节详细解释了它的用法及其特性,如重叠大小?
操作符只返回字符串、序列表(键为1到n,没有孔)或定义“len”元方法的对象的长度。请注意,字符串的长度是字节数,而字节数不一定等于字符数(请考虑UTF-8等)。感谢您的解释:)