我正在尝试用其他文字替换一些文字。简单吧?嘿。
首先,我有一串文字:
local str = "This is some >>1234 text. This is some >>>/other/1234 text."
你会在文本中注意到有趣的格式。我需要用HTML替换它们。但有一个问题:我需要使用该格式中的数据访问数据库。我使用以下格式来获取数据:
local pattern1 = ">>(%d+)"
local pattern2 = ">>>/(%w+)/(%d*)"
在这两种模式中,我都需要使用%d
部分来检查数据库。原因在于,根据数据,我需要以不同方式格式化链接。最终,我希望有这样的东西:
local formatted = "This is some <a href='website.com/a/1220#1234'>>>1234</a> text. This is some <a href='website.com/other/1156#1234'>>>>/other/1234</a> text."
所以我第一次尝试在string.gsub中对匹配的每个实例运行一个函数。这导致了C-yield错误,因为我试图访问协程中的C junk(数据库驱动程序),正如我所知,这是一个禁忌。
我不确定我的第二次尝试应该是什么。我想我需要使用string.match迭代文本来提取我想要抓取的地方的索引,然后使用gsub获取我需要访问数据库并存储在某处的数据,然后从头开始重建字符串。
这是正确的,还是有更好的方法?
Error
attempt to yield across C-call boundary
Traceback
stack traceback:
[C]: in function 'receive'
/home/karai/.luarocks/share/lua/5.1/pgmoon/init.lua:419: in function 'receive_message'
/home/karai/.luarocks/share/lua/5.1/pgmoon/init.lua:233: in function 'query'
/usr/share/lua/5.1/lapis/db/postgres.lua:64: in function 'select'
./src/text_formatter.lua:39: in function <./src/text_formatter.lua:24>
[C]: in function 'gsub'
./src/text_formatter.lua:55: in function 'quote'
./src/board.lua:58: in function 'handler'
/usr/share/lua/5.1/lapis/application.lua:399: in function 'resolve'
/usr/share/lua/5.1/lapis/application.lua:408: in function </usr/share/lua/5.1/lapis/application.lua:406>
[C]: in function 'xpcall'
/usr/share/lua/5.1/lapis/application.lua:406: in function 'dispatch'
/usr/share/lua/5.1/lapis/nginx.lua:205: in function 'serve'
content_by_lua(nginx.conf.compiled:27):2: in function <content_by_lua(nginx.conf.compiled:27):1>
答案 0 :(得分:4)
您的问题的核心似乎是您希望在每次匹配时产生(大概是在数据库查询完成之前),然后继续处理。
为此,您应首先使用gmatch
。它执行gsub
所做的事情,但没有替换;它返回一个迭代器,你可以循环返回匹配。因此,使用它来生成查询列表。这应该存储在一个数组中:
local matches = {}
for match in my_string:gmatch(pattern) do
matches[#matches + 1] = match
end
然后只需走数组,做你的数据库/产量。
local repls = {}
for i, match in ipairs(matches) do
--Do database query&yield stuff with `match`.
repls[i] = --Generate the data you want to replace this match with.
end
之后,只需gsub
替换字符串即可。与gmatch
和gsub
匹配的顺序是相同的,因此您无需关心参数:
local i = 0 --Not zero-based; keep reading
local fixed_string = my_string:gsub(pattern,
function() --Don't care about the arguments.
i = i + 1
return repls[i] --Started at zero, so that this would be correct.
end
)