摘自:http://www.daileinote.com/computer/openresty/10
ngx_lua 在表 ngx.re 里提供了5个正则表达式相关函数,它们的底层实现为 nginx 的 PCRE 库,并且支持 PCRE-JIT,速度非常快,完全可以代替 Lua 标准库的字符串匹配函数。
ngx.re.match
1 | syntax: captures, err = ngx.re.match(subject, regex, options?, ctx?, res_table?) |
返回第一个匹配,没匹配或报错返回 nil。
捕获的结果存在 captures 里,captures[0] 代表全部,captures[1] 代表第一个括号的捕获值,没捕获到的返回 nil。
1 | local m, err = ngx.re.match("hello, 1234", "[0-9]+") |
支持命名捕获
1 | local m, err = ngx.re.match("hello, 1234", "([0-9])(?<remaining>[0-9]+)") |
没捕获到的返回 false。
1 | location = /test { |
下面是常用的选项:
i 大小写不敏感
j 开启 PCRE JIT 预编译
o 编译一次模式,开启 worker 进程对编译过的 regex 缓存
J PCRE Javascript 兼容模式
m 多行模式
s 单行模式
u utf-8模式
U utf-8模式,只是不检测 utf-8有效性检测
x 扩展模式
1 | local m, err = ngx.re.match("hello, world", "HEL LO", "ix") |
-o 指令可以让 worker 进程缓存编译过的regex,lua_regex_cache_max_entries 指令可以用来设置缓存的个数。
可选的 ctx 参数是一个表格,里面可以有一个可选成员 pos,如果没指定,那么将在 ctx 里面设置 pos 为匹配到的字符串末尾偏移量。如果指定,那么为匹配偏移量。
1 | local ctx = {} |
ngx.re.find
1 | syntax: from, to, err = ngx.re.find(subject, regex, options?, ctx?, nth?) |
类似 ngx.re.match ,只是 from 代表匹配的开始,to 代表结尾。
如果不需要捕获,最好用这个函数,不创建新的字符串或者表格,速度快。
1 | local s = "hello, 1234" |
第五个参数 nth 代表从第几个子捕获算偏移,默认为0。
1 | local str = "hello, 1234" |
ngx.re.gmatch
1 | syntax: iterator, err = ngx.re.gmatch(subject, regex, options?) |
类似 ngx.re.match,只是返回迭代。
1 | local it, err = ngx.re.gmatch("hello, world!", "([a-z]+)", "i") |
ngx.re.sub
1 | syntax: newstr, n, err = ngx.re.sub(subject, regex, replace, options?) |
替换第一次匹配并返回替换后的结果,n代表替换的次数。
1 | local newstr, n, err = ngx.re.sub("hello, 1234", "([0-9])[0-9]", "[$0][$1]") |
$0、${0}代表全匹配,$1、${1}代表第一个子匹配,如果需要使用 $,可以使用 $$。
1 | local newstr, n, err = ngx.re.sub("hello, 1234", "[0-9]", "${0}00") |
如果指定 replace 为函数,那么可以通过函数模式组装替换后的字符串。
1 | local func = function (m) |
ngx.re.gsub
1 | syntax: newstr, n, err = ngx.re.gsub(subject, regex, replace, options?) |
同上,只是全局替换而不是只替换第一次匹配。
1 | local newstr, n, err = ngx.re.gsub("hello, world", "([a-z])[a-z]+", "[$0,$1]", "i") |