Lua 中的字符串是不可变的。这意味着,任何替换字符串中文本的解决方案最终都必须构造一个具有所需内容的新字符串。对于将单个字符替换为其他内容的特定情况,您需要将原始字符串拆分为前缀部分和后缀部分,然后将它们重新连接到新内容周围。
您的代码的这种变体:
function replace_char(pos, str, r)
return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
是直接 Lua 的最直接翻译。对于大多数目的来说,它可能已经足够快了。我已经修复了前缀应该是第一个 pos-1 字符的错误,并利用了这样一个事实,即如果 string.sub 的最后一个参数丢失,则假定它是 -1,这相当于字符串。
但请注意,它会创建一些临时字符串,这些字符串将在字符串存储中徘徊,直到垃圾收集吃掉它们。在任何解决方案中都无法避免前缀和后缀的临时性。但这也必须为第一个 .. 运算符创建一个临时运算符,以供第二个运算符使用。
两种替代方法中的一种可能会更快。第一个是solution offered by Paŭlo Ebermann,但稍作调整:
function replace_char2(pos, str, r)
return ("%s%s%s"):format(str:sub(1,pos-1), r, str:sub(pos+1))
end
这使用string.format 进行结果的组装,希望它可以猜测最终的缓冲区大小而不需要额外的临时对象。
但请注意,string.format 可能会在通过其%s 格式传递的任何字符串中的任何\0 字符出现问题。具体来说,由于它是根据标准 C 的 sprintf() 函数实现的,因此期望它在第一次出现 \0 时终止替换字符串是合理的。 (用户 Delusional Logic 在评论中注明。)
想到的第三种选择是:
function replace_char3(pos, str, r)
return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)}
end
table.concat 有效地将字符串列表连接成最终结果。它有一个可选的第二个参数,它是要在字符串之间插入的文本,默认为"",这符合我们的目的。
我的猜测是,除非您的字符串很大并且您经常执行此替换,否则您不会看到这些方法之间的任何实际性能差异。但是,我之前曾感到惊讶,因此请分析您的应用程序以验证是否存在瓶颈,并仔细对潜在解决方案进行基准测试。