local TAG = "string.find: "
print(TAG, string.find("1+1=2", "1+1"))
各位先思考一下,这个函数应该如何来写?
1秒过去了......
2秒过去了......
3秒过去了......
......
好了,为了方便大家理解 string.gsub() 的用法,我用两种方式来写吧。
第一种:
参数2 是一个pattern,
参数3 是一个函数,string.gsub会把匹配得到的结果作为函数参数传入,函数内切莫忘了return。
第二种:
参数2 里多了一对括号,表示捕获截取到的字符串。
参数3 如果参数2里有多个括号,则 %1 对应第一个括号里捕获的内容,%2 对应第二个括号捕获的内容,一次类推。gsub会把捕获出的内容,按参数3的格式去替换原来的字符串。
至于第二种方案里,为什么要用到3个 % ,这个请大家自己去测试。
测试代码:
看看是不是每个+号前都多了一个%?
|
print(TAG, string.find("1+1=2", "1+1"))
print(TAG, string.find("1+1=2", ConvertSpecialChar("1+1")))
print(TAG, string.find("1+1=2", "1%+1"))
print(ConvertSpecialChar("1+1"))
顺便看了一下 lstrlib.c ,里面包含了 Lua 的string库实现。找到 str_find_aux 函数,是这样的:
static int str_find_aux (lua_State *L, int find) {
size_t l1, l2;
const char *s = luaL_checklstring(L, 1, &l1);
const char *p = luaL_checklstring(L, 2, &l2);
ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
if (init < 0) init = 0;
else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
if (find && (lua_toboolean(L, 4) || /* explicit request? */
strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
/* do a plain search */
const char *s2 = lmemfind(s+init, l1-init, p, l2);
if (s2) {
lua_pushinteger(L, s2-s+1);
lua_pushinteger(L, s2-s+l2);
return 2;
}
}
else {
MatchState ms;
int anchor = (*p == '^') ? (p++, 1) : 0;
const char *s1=s+init;
ms.L = L;
ms.src_init = s;
ms.src_end = s+l1;
do {
const char *res;
ms.level = 0;
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
lua_pushinteger(L, s1-s+1); /* start */
lua_pushinteger(L, res-s); /* end */
return push_captures(&ms, NULL, 0) + 2;
}
else
return push_captures(&ms, s1, res);
}
} while (s1++ < ms.src_end && !anchor);
}
lua_pushnil(L); /* not found */
return 1;
}
最后,如果大家有兴趣,可以再去测试一下如下代码:
local TAG = "string.find: "
print(TAG, string.find("1+1=2", ConvertSpecialChar("1+1").."="))
测试一下看能否得到正确的结果。