有一个Lua字符串replace()函数可以比gsub()更快地进行替换吗? [英] Is there a Lua string replace() function for faster replacements than gsub()?
问题描述
我看到Lua字符串函数的列表,并且看到.gsub()
,用于全局搜索和替换:
I see a list of Lua string functions and I see the .gsub()
, for global search and replace: http://www.gammon.com.au/scripts/doc.php?general=lua_string
所有lua字符串函数:
All lua string functions :
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()
如此高效以至没有好处吗?
Why is there no simple, fast, litteral (non-regex) string replace function?
Is .gsub()
so efficient that there is no benefit?
我发现这是2006年写的,但似乎并未包含在内: http://lua-users .org/wiki/StringReplace
I found this written in 2006 but it does not seem like it's included: http://lua-users.org/wiki/StringReplace
推荐答案
这可能是因为 gsub
能够完全执行replace
函数的功能,而Lua的
This is likely because gsub
is capable of doing exactly what a replace
function would do, and Lua's design goals include that of a small, generally uncomplicated standard library. There's no need for a redundancy like this to be baked right into the language.
作为外部示例,Ruby编程语言在其标准库中同时提供了String#gsub
和String#replace
.由于这样的决定,Ruby是开箱即用的语言.
As an outside example, the Ruby programming language provides both String#gsub
and String#replace
in its standard library. Ruby is a much, much larger language out of the box because of decisions like this.
但是,Lua以它是一种非常容易扩展的语言而自豪.您显示的链接显示了整体编译Lua时如何将函数烘焙到标准库中.您也可以将其拼凑在一起以创建模块.
However, Lua prides itself on being a very easy language to extend. The link you've shown shows how to bake the function into the standard library when compiling Lua as a whole. You could also piece it together to create a module.
将需要的结果快速修补在一起(请注意,我们需要lmemfind函数="nofollow"> lstrlib.c ):
Quickly patching together the parts we need results in (note we need the lmemfind
function from lstrlib.c):
#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
的任何其他模块一样将其加载到Lua中.
We can compile this into a shared object with the proper linkage (cc -shared
, cc -bundle
, etc...), and load it into Lua like any other module with require
.
local replace = require 'strrep'
print(replace('hello world', 'hello', 'yellow')) -- yellow world, 1.0
此答案是对以上评论的正式重构.
这篇关于有一个Lua字符串replace()函数可以比gsub()更快地进行替换吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!