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

5

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

##### 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"

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

2个回答

10

你可以使用

local pattern = ".*abc '([^']+)'"
.*是贪婪的,因此它在匹配之前会尽可能多地吞掉输入(在这种情况下,它会吞掉所有之前的匹配并给出最后一个匹配结果)。
或者,如果你真的想要的话,可以反转字符串和模式,但我认为依靠贪婪的.*更好。 :P
pattern = "'([^']+)' cba"
print(text:reverse():gmatch(pattern)())           -- rab
print(text:reverse():gmatch(pattern)():reverse()) -- bar

0

另外一个选择是使用$模式锚定符将模式锚定在字符串的结尾。在这里,您也不需要使用gmatch,只需要使用match就可以了(并且可以避免调用由gmatch返回的迭代器函数)。总之,您可以得到以下代码:

text:match"'([^']+)'$"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接