【问题标题】:return offset of a string with lua使用 lua 返回字符串的偏移量
【发布时间】:2012-02-13 01:02:28
【问题描述】:

我正在尝试在相当大的文件中搜索某个字符串并返回其偏移量。我是 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

我意识到这种方式相当原始,而且速度肯定很慢。我怎样才能更有效地做到这一点?

提前致谢。

【问题讨论】:

    标签: string lua find return offset


    【解决方案1】:

    如果文件不是太大,并且你可以节省内存,那么在整个文件中啜饮并使用string.find会更快。如果没有,您可以按块搜索文件。

    你的方法还不错。不过,我建议将文件加载到重叠的块中。重叠避免了模式仅在块之间拆分而被忽视,例如:

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

    我的实现是这样的:

    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
    

    如果你的文件确实有行,你也可以使用here 解释的技巧。 《Lua 编程》一书中的This section 解释了读取文件时的一些性能注意事项。

    【讨论】:

    • 非常感谢您的示例!它就像一个魅力。我完成了第 21.1 节。在发布我的问题之前阅读 lua 代码书,但我错过了 21.2.1,所以感谢您的提示!我还不熟悉“#”符号的概念。显然你是用它来创建重叠的,但是在 lua 代码书中是否有一节详细解释了它的用法和它的特性,例如重叠大小?
    • # 运算符仅返回字符串的长度、作为序列的表(键是 1 到 n,没有孔)或定义 __len 元方法的对象。请注意,字符串的长度是字节数,不一定等于字符数(想想UTF-8之类的)。
    • 谢谢你的解释:)
    【解决方案2】:

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

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

    【讨论】:

    • 感谢您的快速回复!我用进程监视器解析了 io.lines 读取行为,它显示文件是以 4096 字节的块读取的,所以我认为这是 io.lines 的标准值。你的解决方案让我直截了当。再次感谢!
    猜你喜欢
    • 2017-10-25
    • 2013-01-13
    • 2020-03-09
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多