在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的捕获。
原文链接 https://stackoverflow.com/questions/5249629
Lua 中的字符串是不可变的。这意味着,任何替换字符串中文本的解决方案都必须最终构造一个带有所需内容的新字符串。对于替换单个字符的特定情况,您需要将原始字符串拆分为前缀部分和后缀部分,并围绕新内容将它们重新连接在一起。
这是您的代码的变体:
function replace_char(pos, str, r)
return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
这是最直接的将其转换为简单的 Lua 代码。对于大多数目的来说,它可能已经足够快了。我已经修复了前缀应该是前 pos-1
个字符的 bug,并利用了这样一个事实,即如果 string.sub
的最后一个参数缺失,则假定为 -1
,这相当于字符串的结尾。
但请注意,它会创建大量临时字符串,这些字符串将一直挂在字符串存储区中,直到垃圾回收吞噬它们。前缀和后缀的临时变量在任何解决方案中都无法避免。但是,这还必须创建一个临时变量,以使第一个 ..
运算符被第二个运算符消耗。
可能有两种替代方法中的一种更快。第一种是 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
来组合结果,希望可以猜测出最终缓冲区的大小,从而不需要额外的临时对象。
但请注意,如果任何字符串中有 \0
字符,则 string.format
可能会出现问题。特别是,由于它是基于标准 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
可以高效地将字符串列表连接成最终结果。它有一个可选的第二个参数,它是要插入字符串之间的文本,默认为 ""
,适用于我们在这里的目的。
我的猜测是,除非您的字符串很大并且您经常进行此替换,否则您不会在这些方法之间看到任何实际性能差异。但是,我以前也曾感到惊讶,因此请分析您的应用程序以验证存在瓶颈,并仔细测试潜在的解决方案。
使用 luajit,您可以使用 FFI 库将字符串转换为无符号字符列表:
local ffi = require 'ffi'
txt = 'test'
ptr = ffi.cast('uint8_t*', txt)
ptr[1] = string.byte('o')
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你应该在函数内使用
pos
,而不是字面上的1
和3
。但除此之外看起来很好。由于 Lua 字符串是不可变的,你不能比此更好。也许:
"%s%s%s":format(str:sub(1,pos-1), r, str:sub(pos+1, str:len())
比
..
运算符更有效率,但我怀疑这一点——如果它成为瓶颈,请测量它(然后决定在 C 中实现此替换函数)。