Lua:在字符串中替换字符列表

10
能否在Lua中按照列表替换字符,类似于Perl中的?例如,我想将A替换为B,将B替换为A(例如AABBCC变成BBAACC)。
在Perl中,解决方案是$str ~= tr/AB/BA/。在Lua中是否有本地方法来实现此操作?如果没有,最好的解决方案应该是遍历整个字符串,因为单独的替换需要使用特殊符号来区分已经替换和未替换的字符。
编辑:我的目标是计算DNA字符串的“反向互补” ,如这里所述。
2个回答

16

string.gsub可以将表作为第三个参数。对于每个匹配项,使用第一个捕获组作为键来查询表,并使用关联值作为替换字符串。如果该值为nil,则不更改匹配项。

因此,您可以像这样构建辅助表:

local s = "AABBCC"
local t = {A = "B", B = "A"}
local result = string.gsub(s, "[AB]", t)
print(result)

或者使用同样的一行代码:
print((string.gsub("AABBCC", "[AB]", {A = "B", B = "A"})))

输出:

BBAACC

对于像"[AB]"这样的单个字符模式,"."同样可以工作,因为表中找不到的任何内容都不会被更改。(但我认为这并不更有效) 但是对于一些更复杂的情况,需要一个好的模式。
下面是《Lua编程》(Programming in Lua)书籍中的一个例子:此函数将全局变量varname的值替换为字符串中每个$varname的出现。
function expand (s)
    return (string.gsub(s, "$(%w+)", _G))
end

+1 我不知道gsub的表格形式。比我使用的函数方法好多了。 - HennyH
很棒的解决方案!你觉得我们将"[A|B]"替换为"."(匹配任何字符)会更有效率吗?我已经测试过,结果是一样的。 - Fábio Perez
1
@FábioPerez 是的。 @YuHao lua-patterns 不支持像正则表达式那样的 | 匹配。此外,[AB] 也可以很好地工作。 - hjpotter92

1
下面的代码将使用所需的映射替换每个字符(如果没有映射,则保持不变)。如果您知道字符的确切范围,可以修改trstring.gsub的第二个参数以更具体地指定。
s = "AABBCC"
mappings = {["A"]="B",["B"]="A"}

function tr(s,mappings)
    return string.gsub(s,
        "(.)",
        function(m)
            -- print("found",m,"replace with",mappings[m],mappings[m] or m)
            if mappings[m] == nil then return m else return mappings[m] end
        end 
    )
end

print(tr(s,mappings))

输出

henry@henry-pc:~/Desktop$ lua replace.lua
found   A   replace with    B   B
found   A   replace with    B   B
found   B   replace with    A   A
found   B   replace with    A   A
found   C   replace with    nil C
found   C   replace with    nil C
BBAACC  6

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