String 查找字符串中字符的最后一个索引
我希望能够对我的Lua(Luvit)项目中的字符串使用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
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