Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 查找字符串中字符的最后一个索引_String_Lua - Fatal编程技术网

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

String 查找字符串中字符的最后一个索引,string,lua,String,Lua,我希望能够对我的Lua(Luvit)项目中的字符串使用lastIndexOf方法。不幸的是,没有这种内置的方法,我现在有点卡住了 在Javascript中,它看起来像: 'my.string.here.'.lastIndexOf('.') // returns 14 要在haystack中搜索字符串needle的最后一个实例,请执行以下操作: function findLast(haystack, needle) --Set the third arg to false to

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

在Javascript中,它看起来像:

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

要在
haystack
中搜索字符串
needle
的最后一个实例,请执行以下操作:

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
如果要搜索模式的最后一个实例,请将最后一个参数更改为
find
更改为
false
(或将其删除)


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

如果您有性能问题,那么如果您使用的是使用LuaJIT的Luvit,这可能会快一点

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
开始 的位置捕捉

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可以是任意长度的字符串。 第一个返回值是的第一个字符的位置 substr在str中,第二个返回值是 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

可以优化,但很简单,可以完成工作

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

您的示例为我返回了
1
。抱歉,从内存中-我一定忘记了Lua字符串是如何工作的。您到底想解决什么问题?我认为最简单的方法就是使用
string.find
('my.string.here'):find(%..^.]-$”
)。但是您需要转义特殊字符(例如
*
+
等)。同样在Lua中,结果应该是15。@moteus是一个很好的建议,但我想要一个通用的解决方案(例如,查找数字的索引)@lhf你为什么还要问这个问题?子字符串中字符串的第一个和最后一个索引是所有编程语言中广泛使用的函数!他没有必要解释任何具体问题……发现这篇关于性能的有趣帖子-,只是好奇这个答案是否与性能有关-?@Kosmetika确实很有趣。我以前没见过它,但我写的东西非常接近于
lastIndexOfFind
。唯一的区别是,我的函数返回的是
nil
,而不是
-1
,后者更像Lua风格。哦,我的函数从
string.find的第二个返回值中提取,这意味着它跳过了一些不必要的子字符串,理论上更快。我相信@lhf的答案在普通Lua上性能更好,而在luajit2.1上性能更差,这是因为
string.match
尚未编译,但固定模式
string.find
是,但您必须为您的用例执行自己的测试。
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