博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ngx_lua_API 指令详解(二)ngx.re.match/find/gmatch/sub/gsub指令集合
阅读量:6387 次
发布时间:2019-06-23

本文共 6129 字,大约阅读时间需要 20 分钟。

1、先来个官方的ngx.re.match

location /ngx_re_match {  default_type text/html;  content_by_lua_block {      local m, err = ngx.re.match("/live/4001493201083.m3u8", "[0-9]+")       if m then           -- m[0] == "4001493201083"           ngx.say("makcj::",m[0])       else           if err then               ngx.log(ngx.ERR, "error: ", err)               return           end           ngx.say("match not found")       end  }}

分享:以上可以匹配nginx的uri里面的变量很方便。

2、ngx.re.match 指令

语法: captures,err = ngx.re.match(subject,regex,options?ctx?res_table?)

上下文: init_worker_by_lua *,set_by_lua *,rewrite_by_lua *,access_by_lua *,content_by_lua *,header_filter_by_lua *,body_filter_by_lua *,log_by_lua *,ngx.timer。*,balancer_by_lua *,ssl_certificate_by_lua *,ssl_session_fetch_by_lua *,ssl_session_store_by_lua *

subject使用regex可选的Perl兼容正则表达式匹配字符串options。

只有匹配的第一次出现被返回,或者nil如果没有匹配。在出现错误的情况下,如看到错误的正则表达式或超过PCRE堆栈限制,nil并返回描述错误的字符串。

当发现匹配时,captures返回一个Lua表,其中captures[0]保持整个子串匹配,并captures[1]保存第一个括号子模式的捕获,captures[2]第二个等等。

#demo1

local m, err = ngx.re.match("Tinywan, 1234", "([0-9])[0-9]+")ngx.say("match_value  m[0]:",m[0])ngx.say("match_value  m[1]:",m[1])

输出:

match_value  m[0]:1234match_value  m[1]:1

说明:很简单的,不必解释

#demo2

local m, err = ngx.re.match("hello, 1234", "([0-9])(?
[0-9]+)")ngx.say("match_value m[0]:",m[0])ngx.say("match_value m[1]:",m[1])ngx.say("match_value m[2]:",m[2])ngx.say("match_value m['remaining']:",m["remaining"])

输出

match_value  m[0]:1234match_value  m[1]:1match_value  m[2]:234match_value  m['remaining']:234

说明:命名捕获,并在与编号捕获的键值对相同​​的Lua表中返回

 

3、ngx.re.find

语法: from,to,err = ngx.re.find(subject,regex,options?ctx?,nth?)

上下文: init_worker_by_lua *,set_by_lua *,rewrite_by_lua *,access_by_lua *,content_by_lua *,header_filter_by_lua *,body_filter_by_lua *,log_by_lua *,ngx.timer。*,balancer_by_lua *,ssl_certificate_by_lua *,ssl_session_fetch_by_lua *,ssl_session_store_by_lua *

该方法与ngx.re.match方法基本类似,不同的地方在于ngx.re.find返回的是匹配的字串的起始位置索引和结束位置索引,如果没有匹配成功,那么将会返回两个nil,如果匹配出错,还会返回错误信息到err中。

#demo1

local s = "hello Tinywan, 123456"local from, to, err = ngx.re.find(s, "([0-9]+)", "jo")if from then    ngx.say("from: ", from)    ngx.say("to: ", to)    ngx.say("matched: ", string.sub(s, from, to))else    if err then        ngx.say("error: ", err)        return    end    ngx.say("not matched!")end

输出:

from: 16to: 21matched: 123456

说明:字符串s的长度为21个字节,from:表示匹配成功的索引开始位置,to:则为结束位置,而配置的字符串长度为:to-from+1

!!!官方推荐理由:因为这个API函数不会创建新的Lua字符串或新的Lua表,它比ngx.re.match快得多。应尽可能使用。

  自0.9.3发布以来,支持可选的第五个参数,nth以指定要返回哪个(子匹配)捕获的索引。当nth为0(默认为)时,返回整个匹配子字符串的索引; 何时nth为1,则返回第一个配对捕获的索引; 当nth为2时,则返回第二次匹配捕获,依此类推。当指定的子配对不匹配时,nil将返回两个值

local str = "hello Openresty, 1234878787"local from, to = ngx.re.find(str, "([0-9])([0-9]+)", "jo", nil, 2)if from then    ngx.say("matched 2nd submatch: ", string.sub(str, from, to))  end

输出:matched 2nd submatch: 234878787

4、ngx.re.gmatch

语法: iterator,err = ngx.re.gmatch(subject,regex,options?)

上下文: init_worker_by_lua *,set_by_lua *,rewrite_by_lua *,access_by_lua *,content_by_lua *,header_filter_by_lua *,body_filter_by_lua *,log_by_lua *,ngx.timer。*,balancer_by_lua *,ssl_certificate_by_lua *,ssl_session_fetch_by_lua *,ssl_session_store_by_lua *

与ngx.re.match类似,但是返回一个Lua迭代器,以便让用户程序员<subject>使用PCRE 对string参数的所有匹配进行迭代regex。如果出现错误,就像看到形式不正常的正则表达式,nil并且将返回描述错误的字符串

#demo1

local iterator, err = ngx.re.gmatch("hello, world!", "([a-z]+)", "i")if not iterator then    ngx.log(ngx.ERR, "error: ", err)    returnendlocal mm, err = iterator()    -- m[0] == m[1] == "hello"ngx.say(" 1 m[0] == ",m[0]," m[1] == ",m[1])if err then    ngx.log(ngx.ERR, "error: ", err)    returnendm, err = iterator()    -- m[0] == m[1] == "world"ngx.say(" 2 m[0] == ",m[0]," m[1] == ",m[1])if err then    ngx.log(ngx.ERR, "error: ", err)    returnendm, err = iterator()    -- m == nilif err then    ngx.log(ngx.ERR, "error: ", err)    returnend

输出:

1 m[0] == hello m[1] == hello 2 m[0] == world m[1] == world

#demo2

local it, err = ngx.re.gmatch("hello, world!", "([a-z]+)", "i")if not it then    ngx.log(ngx.ERR, "error: ", err)    returnendwhile true do    local m, err = it()    if err then        ngx.log(ngx.ERR, "error: ", err)        return    end    if not m then        -- no match found (any more)        break    end    -- found a match    ngx.say(m[0])    ngx.say(m[1])end

输出:

hellohelloworldworld

可选options参数与ngx.re.match方法完全相同的语义。

当前的实现需要仅在单个请求中使用返回的迭代器。也就是说,不应该将它分配给属于持久命名空间的变量,如Lua包。

该方法需要在Nginx中启用PCRE库。

 

5、ngx.re.sub

语法: newstr,n,err = ngx.re.sub(subject,regex,replace,options?)

上下文: init_worker_by_lua *,set_by_lua *,rewrite_by_lua *,access_by_lua *,content_by_lua *,header_filter_by_lua *,body_filter_by_lua *,log_by_lua *,ngx.timer。*,balancer_by_lua *,ssl_certificate_by_lua *,ssl_session_fetch_by_lua *,ssl_session_store_by_lua *

将带有字符串或函数参数regex的subject参数字符串的Perl兼容正则表达式的第一个匹配替换replace。可选options参数与ngx.re.match具有完全相同的含义。

此方法返回所生成的新字符串以及成功替换的数量。在出现故障的情况下,如正则表达式或<replace>字符串参数中的语法错误,它将返回nil一个描述该错误的字符串。

当replace是字符串时,它被视为用于字符串替换的特殊模板

#demo1

local newstr, n, err = ngx.re.sub("hello, 1234", "([0-9])[0-9]", "[$0][$1]")if newstr then    -- newstr == "hello, [12][1]34"    -- n == 1    ngx.say("newstr == ",newstr)else    ngx.log(ngx.ERR, "error: ", err)    returnend

输出:

newstr == hello, [12][1]34n == 1

说明:其中$0引用由模式匹配的整个子字符串,并$1引用第一个括号化的捕获子字符串

6、ngx.re.gsub

语法: newstr,n,err = ngx.re.gsub(subject,regex,replace,options?)

上下文: init_worker_by_lua *,set_by_lua *,rewrite_by_lua *,access_by_lua *,content_by_lua *,header_filter_by_lua *,body_filter_by_lua *,log_by_lua *,ngx.timer。*,balancer_by_lua *,ssl_certificate_by_lua *,ssl_session_fetch_by_lua *,ssl_session_store_by_lua *

就像ngx.re.sub一样,但是全局替换

#demo1

local newstr, n, err = ngx.re.gsub("hello, world", "([a-z])[a-z]+", "[$0,$1]", "i")if newstr then   ngx.say("newstr == ",newstr)   ngx.say("n == ",n)else    ngx.log(ngx.ERR, "error: ", err)    return

输出:

newstr == [hello,h], [world,w]n == 2

说明:该方法需要在Nginx中启用PCRE库

#demo2

local func = function (m)    return "[" .. m[0] .. "," .. m[1] .. "]"endlocal newstr, n, err = ngx.re.gsub("hello, world", "([a-z])[a-z]+", func, "i")ngx.say("newstr == ",newstr)ngx.say("n == ",n)

输出:

newstr == [hello,h], [world,w]n == 2

 

转载地址:http://xfcha.baihongyu.com/

你可能感兴趣的文章
Linux软件包安装与卸载
查看>>
centos5.x安装sphinx
查看>>
3分钟搭建Ant Design Pro前端开发环境( MyClouds的前端选型)
查看>>
Scala各种用法
查看>>
Linux系统常用命令(二)
查看>>
简单的工厂模式学习
查看>>
温习如何画E-R图
查看>>
eclispe注释模板
查看>>
Thymeleaf教程 (三) 创建一个多语言的首页
查看>>
OSChina 周六乱弹 ——你们猜狗的舌头有多长
查看>>
OSChina 周日乱弹 —— 爱丽丝爱吃京酱肉丝
查看>>
2018.11月微信小程序优质开源项目
查看>>
IOS 未来几年的认知
查看>>
解决中文乱码--加密
查看>>
浅析全民社交创业梦
查看>>
Java操纵MongoDB_1(环境设置)
查看>>
C#字符串操作--获取字符或字符串的位置、数量
查看>>
php - 字符串处理
查看>>
bulk collect 以及ref cursor使用
查看>>
mysql性能优化-慢查询分析、优化索引和配置
查看>>