lua字符串模式匹配

string.gmatch()不支持匹配首字符

string.gmatch(s, pattern)中,如果s的开头是'^'字符,不会被当成首字符标志,而是被当成一个普通字符。

比如

lua 复制代码
s="hello world from lua"
for w in string.gmatch(s, "^%a+") do
	print(w)
end

不会输出任何内容,而

lua 复制代码
s="hello world from lua"
for w in string.gmatch(s, "^%a+") do
	print(w)
end

会输出^hello。

仿照str_find_aux()的实现修复一下这个问题:

复制代码
 static int gmatch_aux (lua_State *L) {
   MatchState ms;
   size_t ls;
   const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
   const char *p = lua_tostring(L, lua_upvalueindex(2));
+  lua_Integer init = lua_tointeger(L, lua_upvalueindex(3));
+  int anchor = 0;
   const char *src;
+  if(*p == '^') {
+    if(init != 0) return 0;
+    p++;
+    anchor = 1;
+  }
   ms.L = L;
   ms.src_init = s;
   ms.src_end = s+ls;
-  for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
-       src <= ms.src_end;
-       src++) {
+  for (src = s + init; src < ms.src_end; src++) {
     const char *e;
     ms.level = 0;
     if ((e = match(&ms, src, p)) != NULL) {
       lua_Integer newstart = e-s;
       if (e == src) newstart++; /* empty match? go at least one position */
       lua_pushinteger(L, newstart);
       lua_replace(L, lua_upvalueindex(3));
       return push_captures(&ms, src, e);
     }
+    if (anchor) return 0;
   }
   return 0; /* not found */
 }

手册没说明的前端匹配

前端匹配(frontier matching)的格式:%fx(其中x是字符集)。这里,方括号内的内容定义了一组字符集,用来描述匹配的前后边界条件。

工作原理:%fx会尝试匹配一个位置,假设该位置之前的字符是a,该位置之后的字符是b,则a不属于字符集x,b属于字符集x。

和'^'',$'类似,%fx只是去寻找一个位置,而不是特定的字符。

lua 复制代码
-- 只会匹配第二个123
for w in string.gmatch("0123abc123","%f[%d]123") do
	print(w)
end

-- 会匹配两个123
for w in string.gmatch("0123abc123","123") do
	print(w)
end
相关推荐
星空露珠1 天前
28种颜色对应名称,
开发语言·数据库·算法·游戏·lua
吴声子夜歌9 天前
Redis 3.x——事务与Lua
redis·lua
豆瓣鸡11 天前
Redis Lua 脚本——把多条命令打包成一个原子操作
java·redis·lua
橙色阳光五月天13 天前
MATLAB函数如何打包成独立EXE
开发语言·matlab·lua
耀耀_很无聊16 天前
12_Redis Lua 脚本踩坑:为什么 tonumber(ARGV[x]) 会得到 nil?
java·redis·lua
章老师说17 天前
NGINX官方谈Lua风险:这其实是两条网关技术路线之争
运维·nginx·负载均衡·lua·openresty
会周易的程序员18 天前
使用 LuaBridge 封装 C++ 日志库 microLog 为 Lua 模块
c++·物联网·junit·lua·日志·iot·aiot
欢呼的太阳19 天前
在上一篇随笔中介绍了四种编程语言。这次再介绍四种编程语言:Fortran、Lua、Lisp 和 Logo。
junit·lua·lisp
星空露珠20 天前
迷你世界UGc3.0脚本Wiki[剧情动画模块管理接口 Timeline]
开发语言·数据结构·算法·游戏·lua
开开心心_Every20 天前
带OCR识别的电子发票打印工具
运维·自动化·ocr·电脑·powerpoint·音视频·lua