繁体   English   中英

在Lua中修改字符串中的字符

[英]Modifying a character in a string in 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格式的任何字符串中出现任何\\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有效地将字符串列表连接成最终结果。 它有一个可选的第二个参数,它是在字符串之间插入的文本,默认为"" ,这符合我们的目的。

我的猜测是,除非您的字符串很大而且经常进行这种替换,否则您将看不到这些方法之间的任何实际性能差异。 但是,我之前一直感到惊讶,因此请对您的应用程序进行分析,以确认存在瓶颈,并仔细评估潜在的解决方案。

你应该在你的函数中使用pos而不是文字13 ,但除此之外它看起来不错。 因为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')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM