Lua:处理文本输出的所有排列和 return 替代文本

Lua: Process all permutations of text output and return alternative text

我很久以前就这个特定的 Lua 代码寻求帮助,它对我很有帮助。现在我正在寻求对其进行更改,但我不确定我是否以正确的方式进行更改。

首先,在我玩的MUD上,我们有几个标志可以作为装备项的前缀。它们是:(K)(M)(I)(G)(H)。它们将始终按该顺序出现,而不管实际存在哪些标志。例如:

(K)(M)(G)(H)
(M)(H)
(K)(I)(G)

等等。我的代码只是采用上述组合并将其分别更改为 KMGHMHKIG。我现在想做的是匹配任何字母组合和 return 它们被方括号括起来,所以 [KMGH],等等

for i = 1, #TriggerStyleRuns do

    TSRt = TriggerStyleRuns[i].text
    if string.match(TSRt,"(K)") or string.match(TSRt,"(I)") or string.match(TSRt,"(M)") or string.match(TSRt, "(G)") or string.match(TSRt, "(H)") then
        TriggerStyleRuns[i].text = string.gsub(TSRt,"%%((%%w)%%)","%%1")
    end
end

使用上面的代码,我可以设想我的计划发生的唯一方法是展望每个组合,但我真的不想有几行

if string.match(TriggerStyleRuns[i].text, "(K)") and string.match(TriggerStyelRuns[i+1].text, "(M)" and...

因为虽然我可以做到,但需要做很多额外的工作。有没有一种更简单的方法来处理它们并确保找到的第一个元素在开头收到 [ 并且找到的最后一个元素收到 ]?

额外的好处:我想从中去掉 (I) 并用它来给括号上色,这需要我在第一个元素之前 table.insert 并在最后一个元素之后插入元素。如需更多参考,请参阅下面的 TriggerStyleRuns table 样式:

TriggerStyleRuns = {
  {"backcolour"=0,"text"="( 7) ", "length"=5, "style"=1, "textcolour"=16777215}, 
  {"backcolour"=0,"text"="(K)", "length"=3, "style"=1, "textcolour"=255},
  {"backcolour"=0, "text"="(M)", "length"=3, "style"=1, "textcolour"=16711680},
  {"backcolour"=0, "text"="(G)", "length"=3, "style"=1, "textcolour"=16777215},
  {"backcolour"=0, "text"="(H) ", "length"=4, "style"=1, "textcolour"=16776960},
  {"backcolour"=0, "text"="a ", "length"=2, "style"=0, "textcolour"=12632256},
  {"backcolour"=0, "text"="Bag of ", "length"=7, "style"=1, "textcolour"=65535},
  {"backcolour"=0, "text"="Aardwolf", "length"=8, "style"=1, "textcolour"=255},
  {"backcolour"=0, "text"=" ", "length"=1, "style"=0, "textcolour"=12632256},
  {"backcolour"=0, "text"="(", "length"=1, "style"=1, "textcolour"=16777215},
  {"backcolour"=0, "text"="72", "length"=2, "style"=1, "textcolour"=65280},
 {"backcolour"=0, "text"=")", "length"=1, "style"=1, "textcolour"=16777215}
}

索引的数量可以改变,但我最关心的是上面描述的标志。

编辑
for 循环遍历 TriggerStyleRuns table。上面给出了一个例子。如前所述,索引的数量可以改变,这包括标志的数量。例如,如果 (K) 标志不存在,在上面的 table 中,第二个索引将改为 (M) 而不是 (K)。所以本质上,我需要遍历 table,拉出所有标志匹配项,更改这些索引中的文本,并在第一个标志之前和之后的位置创建一个新标志。例如,上面的 table 完成后看起来像这样:

TriggerStyleRuns = {
  {"backcolour"=0,"text"="( 7) ", "length"=5, "style"=1, "textcolour"=16777215}, 
  {"backcolour"=0,"text"="[", "length"=1, "style"=1, "textcolour"=1234567},
  {"backcolour"=0,"text"="K","length"="1", "style"=1, "textcolour"=255}, 
  {"backcolour"=0, "text"="M", "length"=3, "style"=1, "textcolour"=16711680},
  {"backcolour"=0, "text"="G", "length"=3, "style"=1, "textcolour"=16777215},
  {"backcolour"=0, "text"="H ", "length"=4, "style"=1, "textcolour"=16776960},
  {"backcolour"=0,"text"="]", "length"=1, "style"=1, "textcolour"=1234567},
  {"backcolour"=0, "text"="a ", "length"=2, "style"=0, "textcolour"=12632256},
  {"backcolour"=0, "text"="Bag of ", "length"=7, "style"=1, "textcolour"=65535},
  {"backcolour"=0, "text"="Aardwolf", "length"=8, "style"=1, "textcolour"=255},
  {"backcolour"=0, "text"=" ", "length"=1, "style"=0, "textcolour"=12632256},
  {"backcolour"=0, "text"="(", "length"=1, "style"=1, "textcolour"=16777215},
  {"backcolour"=0, "text"="72", "length"=2, "style"=1, "textcolour"=65280},
  {"backcolour"=0, "text"=")", "length"=1, "style"=1, "textcolour"=16777215}
}

我并没有真正理解你的描述,但据我了解,你想要做的是,给定这些字母的任意顺序,return它们按照指定的顺序,用方括号括起来.这是一个选项:

function orderOptions( str )
    local letters = { k = '', m = '', i = '', g = '', h = '' }
    str:gsub( '%((.)%)', function( letter )
        letters[letter] = letter
    end )
    return '[' .. letters.k .. letters.m .. letters.i .. letters.g .. letters.h .. ']'
end

但是有什么问题呢,假设它们的顺序已经正确:

for i = 1, #TriggerStyleRuns do

    TSRt = TriggerStyleRuns[i].text
    if string.match(TSRt,"(K)") or string.match(TSRt,"(I)") or string.match(TSRt,"(M)") or string.match(TSRt, "(G)") or string.match(TSRt, "(H)") then
        TriggerStyleRuns[i].text = string.gsub(TSRt,"%%((%%w)%%)","%%1")
    end
    TriggerStyleRuns[i].text = '[' .. TriggerStyleRuns[i].txt .. ']'
end

编辑:

要从 "(K)(M)(G)" 等格式中获取文本,我会这样做:

-- Assuming 'flags' is the specific string
local str = '['
flags:gsub( '%((.)%)', function( flag )
    str = str .. flag
end )
str = str .. ']'

编辑 2:

阅读您更新后的描述后,我对您的目的有了更好的了解。最好的方法似乎仍然是事先做,但如果你坚持这样做,我想我有一个主意。

因为看起来您正在修改它们所在的 table(而不是创建一个新的),这使事情变得有点复杂,但仍然可行。

local flags = { K = true, M = true, G = true, H = true }

TriggerStyleRuns = {
  {backcolour=0, text="( 7) ", length=5, style=1, textcolour=16777215}, 
  {backcolour=0, text="(K)", length=3, style=1, textcolour=255},
  {backcolour=0, text="(M)", length=3, style=1, textcolour=16711680},
  {backcolour=0, text="(G)", length=3, style=1, textcolour=16777215},
  {backcolour=0, text="(H) ", length=4, style=1, textcolour=16776960},
  {backcolour=0, text="a ", length=2, style=0, textcolour=12632256},
  {backcolour=0, text="Bag of ", length=7, style=1, textcolour=65535},
  {backcolour=0, text="Aardwolf", length=8, style=1, textcolour=255},
  {backcolour=0, text=" ", length=1, style=0, textcolour=12632256},
  {backcolour=0, text="(", length=1, style=1, textcolour=16777215},
  {backcolour=0, text="72", length=2, style=1, textcolour=65280},
  {backcolour=0, text=")", length=1, style=1, textcolour=16777215}
}

local function defaultText( str )
    return {backcolour=0,text=str, length=#str, style=1, textcolour=1234567}
end

local matchStarted -- nil
local i = 0
-- Can't use for loop because we're inserting elements into the same table
while matchStarted ~= false do
    i = i + 1
    local text = TriggerStyleRuns[i].text:match( '%((.)%)' )
    if flags[text] then
        if not matchStarted then
            matchStarted = true
            table.insert( TriggerStyleRuns, i, defaultText( '[' ) )
            i = i + 1 -- Don't want to process a letter twice
        end
        TriggerStyleRuns[i].text = text
        TriggerStyleRuns[i].length = #text
    elseif matchStarted then
        matchStarted = false
        table.insert( TriggerStyleRuns, i, defaultText( ']' ) )
    end
end