String 复杂的字符串替换问题

String 复杂的字符串替换问题,string,replace,lua,String,Replace,Lua,我试图用其他文本替换一些文本。很简单,对吧?呵呵 首先,我有一个字符串: local str = "This is some >>1234 text. This is some >>>/other/1234 text." 您将注意到文本中的有趣格式。我需要用HTML替换它们。但有一个陷阱:我需要使用该格式中的数据访问数据库。我使用以下格式获取数据: local pattern1 = ">>(%d+)" local pattern2 = ">>

我试图用其他文本替换一些文本。很简单,对吧?呵呵

首先,我有一个字符串:

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."
local formatted=“这是一些文本。这是一些文本。”
因此,我的第一次尝试是在string.gsub中的每个匹配实例上运行一个函数。这导致了C-yield错误,因为我试图访问协同程序中的C垃圾(数据库驱动程序),据我所知,这是不允许的

我不确定我的第二次尝试应该是什么。我想我需要用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>
错误
试图跨越C-call边界让步
回溯
堆栈回溯:
[C] :在“接收”功能中
/home/karai/.luarocks/share/lua/5.1/pgmoon/init.lua:419:在函数“接收消息”中
/home/karai/.luarocks/share/lua/5.1/pgmoon/init.lua:233:在函数“query”中
/usr/share/lua/5.1/lapis/db/postgres.lua:64:在函数“select”中
./src/text\u格式化程序。lua:39:in函数
[C] :在函数“gsub”中
./src/text_formatter.lua:55:在函数'quote'中
./src/board.lua:58:在函数“handler”中
/usr/share/lua/5.1/lapis/application.lua:399:在函数“resolve”中
/usr/share/lua/5.1/lapis/application.lua:408:在函数中
[C] :在函数“xpcall”中
/usr/share/lua/5.1/lapis/application.lua:406:在函数“dispatch”中
/usr/share/lua/5.1/lapis/nginx.lua:205:函数“服务”
content_by_lua(nginx.conf.compiled:27):2:in函数

您的问题的核心似乎是希望在每次匹配时都让步(大概直到数据库查询完成),然后继续处理

为此,应首先使用
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
)

“访问协同程序中的C垃圾(数据库驱动程序),正如我所了解的,从协同程序中调用C函数通常是不允许的”。现在还不清楚您的问题是什么(或者为什么要使用协同程序)。string.gsub是后台的协同程序。我会加一条追踪路线。哦,我明白了。您正在将一个函数传递到
gsub
以生成替换字符串。你试图让这个函数发出一个收益,通过
gsub
,返回给调用这个过程的人。是的。所以这是一件坏事。正确的方法是什么?