修改Lua中字符串中的字符

有没有办法替换Lua中字符串中位置N处的字符。 这是我到目前为止所提出的:
function replace_char(pos, str, r)
    return str:sub(pos, pos - 1) .. r .. str:sub(pos + 1, str:len())
end

str = replace_char(2, "aaaaaa", "X")
print(str)
我不能使用gsub,因为它会取代每个捕获,而不仅仅是位置N的捕获。     
已邀请:
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
,这相当于字符串的结尾。 但请注意,它会创建一些临时字符串,这些字符串将在字符串存储中挂起,直到垃圾回收占用它们。在任何解决方案中都无法避免前缀和后缀的临时性。但这也必须为第一个
..
操作员创建一个临时的第二个消费者。 两种替代方法中的一种可能更快。第一个是PaŭloEbermann提供的解决方案,但有一个小调整:
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
格式。具体来说,由于它是根据标准C的
sprintf()
函数实现的,因此期望它在第一次出现
时终止替换字符串是合理的。 (在评论中由用户Delusional Logic注释。) 想到的第三种选择是:
function replace_char3(pos, str, r)
    return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)}
end
table.concat
有效地将字符串列表连接成最终结果。它有一个可选的第二个参数,它是在字符串之间插入的文本,默认为
""
,这符合我们的目的。 我的猜测是,除非您的字符串很大而且经常进行这种替换,否则您将看不到这些方法之间的任何实际性能差异。但是,我之前一直感到惊讶,因此请对您的应用程序进行分析,以确认存在瓶颈,并仔细评估潜在的解决方案。     
你应该在你的功能中使用
pos
而不是文字
1
3
,但除此之外它看起来不错。因为Lua字符串是不可变的,所以你不能比这更好。 也许
 "%s%s%s":format(str:sub(1,pos-1), r, str:sub(pos+1, str:len())
..
算子更有效,但我对此表示怀疑 - 如果它成为瓶颈,则测量它(然后决定在C中实现这个替换函数)。     
使用luajit,您可以使用FFI库将字符串转换为无符号图表列表:
local ffi = require 'ffi'
txt = 'test'
ptr = ffi.cast('uint8_t*', txt)
ptr[1] = string.byte('o')
    

要回复问题请先登录注册