Lua 有一个替换字符串的函数,比 gsub() 更快吗?
2016-7-17 8:56:0
收藏:0
阅读:104
评论:1
我看到 Lua 中有一堆字符串函数,其中 .gsub() 可以全局查找和替换:http://www.gammon.com.au/scripts/doc.php?general=lua_string
所有的 Lua 字符串函数:
static const luaL_Reg strlib[] = {
{"byte", str_byte},
{"char", str_char},
{"dump", str_dump},
{"find", str_find},
{"format", str_format},
{"gfind", gfind_nodef},
{"gmatch", gmatch},
{"gsub", str_gsub},
{"len", str_len},
{"lower", str_lower},
{"match", str_match},
{"rep", str_rep},
{"reverse", str_reverse},
{"sub", str_sub},
{"upper", str_upper},
{NULL, NULL}
};
为什么没有一个简单、快速、文字(非正则表达式)替换函数?
.gsub() 速度很快,是否没有更好的替换函数?
我发现这篇文章是在 2006 年写的,但似乎并没有被包含在内:http://lua-users.org/wiki/StringReplace
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在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中获取用户配置主目录的跨平台方法
这可能是因为
gsub可以完全胜任replace函数的任务,Lua 的 设计目标 包括创建一个小型、通常不复杂的标准库,不需要将此类功能作为冗余功能内建到语言中。以外部示例为例,Ruby 编程语言在其标准库中提供了
String#gsub和String#replace。由于做出了这样的决策,Ruby 是一个非常庞大的语言。然而,Lua 自豪地成为一门非常易于扩展的语言。你提供的链接显示了如何在编译整个 Lua 时将该函数嵌入到标准库中。你也可以把它拼凑成一个模块。
将我们需要的部分快速拼凑在一起的结果如下(注意,我们需要从 lstrlib.c 中获取
lmemfind函数):#include <lua.h> #include <lauxlib.h> #include <string.h> static const char *lmemfind (const char *s1, size_t l1, const char *s2, size_t l2) { if (l2 == 0) return s1; /* empty strings are everywhere */ else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ const char *init; /* to search for a '*s2' inside 's1' */ l2--; /* 1st char will be checked by 'memchr' */ l1 = l1-l2; /* 's2' cannot be found after that */ while (l1 > 0 && (init = (const char *) memchr(s1, *s2, l1)) != NULL) { init++; /* 1st char is already checked */ if (memcmp(init, s2+1, l2) == 0) return init-1; else { /* correct 'l1' and 's1' to try again */ l1 -= init-s1; s1 = init; } } return NULL; /* not found */ } static int str_replace(lua_State *L) { size_t l1, l2, l3; const char *src = luaL_checklstring(L, 1, &l1); const char *p = luaL_checklstring(L, 2, &l2); const char *p2 = luaL_checklstring(L, 3, &l3); const char *s2; int n = 0; int init = 0; luaL_Buffer b; luaL_buffinit(L, &b); while (1) { s2 = lmemfind(src+init, l1-init, p, l2); if (s2) { luaL_addlstring(&b, src+init, s2-(src+init)); luaL_addlstring(&b, p2, l3); init = init + (s2-(src+init)) + l2; n++; } else { luaL_addlstring(&b, src+init, l1-init); break; } } luaL_pushresult(&b); lua_pushnumber(L, (lua_Number) n); /* number of substitutions */ return 2; } int luaopen_strrep (lua_State *L) { lua_pushcfunction(L, str_replace); return 1; }我们可以使用适当的链接(
cc -shared、cc -bundle等)将其编译成共享对象,并像加载任何其他模块一样使用require加载它。local replace = require 'strrep' print(replace('hello world', 'hello', 'yellow')) -- yellow world, 1.0此答案是对上述评论的正式重构。