如何使用参数在Lua中实现rfind函数?

例如,在lua中想要这样做:

s = "Hey\n There And Yea\n"

print(s.rfind("\n", 0, 5))

我尝试使用string.find函数在lua中实现它:

local s = "Hey\n There And Yea\n"

local _, p = s:find(".*\n", -5)

print(p)

但是这两种方法得到的结果不同。我做错了什么,如何修复它,使它与rfind相同?

点赞
用户1008957
用户1008957

Lua有一个不太为人所知的函数string.reverse,它可以将字符串中的所有字符颠倒过来。虽然这很少被使用,但通常可以用这个函数在字符串中进行反向查找。

因此,要实现rfind,你需要在反向原始字符串中搜索 反向 模式,最后进行一些算术运算以获得从原始字符串的偏移量。

这是模拟Python rfind的代码:

function rfind(subject, tofind, startIdx, endIdx)
    startIdx = startIdx or 0
    endIdx = endIdx or #subject
    subject = subject:sub(startIdx+1, endIdx):reverse()
    tofind = tofind:reverse()
    local idx = subject:find(tofind)
    return idx and #subject - #tofind - idx + startIdx + 1 or -1
end

print(rfind("Hello World", "H")) --> 0
print(rfind("Hello World", "l")) --> 9
print(rfind("foo foo foo", "foo")) --> 8
print(rfind("Hello World", "Toto")) --> -1
print(rfind("Hello World", "l", 1, 4)) --> 3

请注意,这个版本的rfind使用Python的索引约定,从0开始,并且在找不到字符串时返回-1。在Lua中,使用基于1的索引并在没有匹配时返回nil会更为一致。修改非常简单。

2020-10-02 21:17:51