在Lua中,如何反转string.find()或string.gmatch()函数?

我有一个包含以下内容的字符串:

##### abc 'foo'
/path/to/filename:1
##### abc 'bar'
/path/to/filename:1

该字符串可能非常长(比如说 50 行),并且不经常更改。

我想获取单引号之间文本的最后一次出现(例如此示例中的 bar)。这类似于其他人的 Python 问题(但那里的答案在我这里不能在 Lua 中工作,在下面看到)。

我可以解析每一行,并将结果放入数组中,然后只需取数组的最后一个元素,但我认为这不太优雅:

local text = [[
    ##### abc 'foo'
    /path/to/filename:1
    ##### abc 'bar'
    /path/to/filename:1
]]

local arr = {}
local pattern = "abc '([^']+)'"
for s in text:gmatch(pattern) do
  table.insert(arr, s)
end
print('last:', arr[#arr])

我有兴趣使用 Lua 字符串模式从末尾搜索字符串。我尝试下面的模式,但是它从开头开始而不是从末尾开始:

local text = [[
    ##### abc 'foo'
    /path/to/filename:1
    ##### abc 'bar'
    /path/to/filename:1
]]

-- FIXME: pattern searches from beginning
local pattern = "abc '([^']+)'.*$"

local s = text:gmatch(pattern)()
assert(s == 'bar', 'expected "bar" but saw "'..s..'"')
print('last:', s)

这会产生:

input:12: expected "bar" but saw "foo"

哪种字符串模式指定了我要查找的“反向搜索”?

原文链接 https://stackoverflow.com/questions/9090173

点赞
stackoverflow用户913184
stackoverflow用户913184

你可以使用

local pattern = ".*abc '([^']+)'"

.* 是贪婪匹配,所以它会在匹配前尽可能多的匹配(在这种情况下,它会匹配所有较早的匹配并给出最后一个)。

或者,如果你真的想做到,你可以颠倒你的字符串和(部分)你的模式,但我认为更好的方法是依靠贪婪的 .* :P

pattern = "'([^']+)' cba"
print(text:reverse():gmatch(pattern)())           -- rab
print(text:reverse():gmatch(pattern)():reverse()) -- bar
2012-02-01 04:14:55
stackoverflow用户7185318
stackoverflow用户7185318

另一个选项是使用 $ 模式锚来将模式锚定在字符串的末尾。在这里你也不需要使用 gmatch,只需要使用 match 就可以了(这样还可以省去调用 gmatch 返回的迭代器函数的需要)。总之,你可以得到:

text:match"'([^']+)'$"
2022-04-30 13:51:57