查找字符串中字符的最后一个索引

时间:2013-12-08 22:23:33

标签: string lua

我希望能够在我的Lua(Luvit)项目中对字符串使用lastIndexOf方法。不幸的是,没有内置的这种方法,我现在有点卡住了。

在Javascript中看起来像:

'my.string.here.'.lastIndexOf('.')     // returns 14

5 个答案:

答案 0 :(得分:10)

function findLast(haystack, needle)
    local i=haystack:match(".*"..needle.."()")
    if i==nil then return nil else return i-1 end
end
s='my.string.here.'
print(findLast(s,"%."))
print(findLast(s,"e"))

请注意,要查找.,您需要将其转义。

答案 1 :(得分:3)

needle中搜索字符串haystack的最后一个实例:

function findLast(haystack, needle)
    --Set the third arg to false to allow pattern matching
    local found = haystack:reverse():find(needle:reverse(), nil, true)
    if found then
        return haystack:len() - needle:len() - found + 2 
    else
        return found
    end
end

print(findLast("my.string.here.", ".")) -- 15, because Lua strings are 1-indexed
print(findLast("my.string.here.", "here")) -- 11
print(findLast("my.string.here.", "there")) -- nil

如果您想要搜索模式的最后一个实例,请将最后一个参数更改为findfalse(或将其删除)。

答案 2 :(得分:3)

如果您有性能问题,那么如果您使用Luvit使用LuaJIT,这可能会更快一些。

local find = string.find
local function lastIndexOf(haystack, needle)
    local i, j
    local k = 0
    repeat
        i = j
        j, k = find(haystack, needle, k + 1, true)
    until j == nil

    return i
end

local s = 'my.string.here.'
print(lastIndexOf(s, '.')) -- This will be 15.

请注意,Lua字符串的开头位于1,而不是JavaScript中的0

答案 3 :(得分:3)

这是一个使用的解决方案 LPeg的位置捕获。

local lpeg      = require "lpeg"
local Cp, P     = lpeg.Cp, lpeg.P
local lpegmatch = lpeg.match

local cache = { }

local find_last = function (str, substr)
  if not (str and substr)
    or str == "" or substr == ""
  then
    return nil
  end
  local pat = cache [substr]
  if not pat then
    local p_substr   = P (substr)
    local last       = Cp() * p_substr * Cp() * (1 - p_substr)^0 * -1
    pat = (1 - last)^0 * last
    cache [substr] = pat
  end
  return lpegmatch (pat, str)
end

find_last()找到字符串中 substr 的最后一次出现 str ,其中 substr 可以是任意长度的字符串。 第一个返回值是第一个字符的位置 在 str 中的 substr ,第二个返回值是该位置 substr 之后的第一个字符(即它等于的长度) 匹配加上第一个返回值)。

用法:

local tests = {
  A    = [[fooA]],                      --> 4, 5
  [""] = [[foo]],                       --> nil
  FOO  = [[]],                          --> nil
  K    = [[foo]],                       --> nil
  X    = [[X foo X bar X baz]],         --> 13, 14
  XX   = [[foo XX X XY bar XX baz X]],  --> 17, 19
  Y    = [[YYYYYYYYYYYYYYYYYY]],        --> 18, 19
  ZZZ  = [[ZZZZZZZZZZZZZZZZZZ]],        --> 14, 17
  --- Accepts patterns as well!
  [P"X" * lpeg.R"09"^1] = [[fooX42barXxbazX]], --> 4, 7
}

for substr, str in next, tests do
  print (">>", substr, str, "->", find_last (str, substr))
end

答案 4 :(得分:0)

可以优化但简单并完成工作。

function lastIndexOf(haystack, needle)
  local last_index = 0
  while haystack:sub(last_index+1, haystack:len()):find(needle) ~= nil do
    last_index = last_index + haystack:sub(last_index+1, haystack:len()):find(needle)
  end
  return last_index
end

local s = 'my.string.here.'
print(lastIndexOf(s, '%.')) -- 15