Lua 正则表达式

转义符号

转义符号 说明
%c 任意控制字符
%d 任意数字
%a 任意字母
%l 任意小写字母
%u 任意大写字母
%p 任意标点符号
%s 任意空白字符
%w 任意字母或数字
%x 任意十六进制数字
%% 字符 ‘%’
%n 换行符
%t 制表符
%f 换页符
%r 回车符
%bxy 匹配以 x 开始,以 y 结束的字符串
%[ 字符 ‘[’
%] 字符 ‘]’

+. ^ 匹配字符串的开始位置 +. $ 匹配字符串的结束位置 +. () 匹配括号内的子表达式

断言

Lookahead 断言

  1. exam(?=ple) 匹配 exam,但只有当 exam 后面跟着的是字符串 ple 时才匹配成功

  2. exam(?!ple) 匹配 exam,但只有当 exam 后面跟着的不是字符串 ple 时才匹配成功

Lookbehind 断言

  1. (?<=exam)ple 匹配 ple,但只有当 ple 前面是字符串 exam 时才匹配成功

  2. (?<!exam)ple 匹配 ple,但只有当 ple 前面不是字符串 exam 时才匹配成功

API

string.find 寻找被匹配的位置

string.find(s, pattern, init, plain)

  • 参数:

    • s: 要匹配的字符串

    • pattern: 匹配模式

    • init: 可选参数,指定匹配的起始位置

    • plain: 可选参数,如果为 true,则忽略 pattern 中的特殊字符

  • 返回值:

    • 如果匹配成功,则返回匹配的起始位置和结束位置

    • 如果匹配失败,则返回 nil

  • 例子:

    1local s = "hello world"
    2local i, j = string.find(s, "hello")
    3print(i, j) -- 1 5
    

string.match 获取匹配的字符串

string.match(s, pattern, init)

  • 参数:

    • s: 要匹配的字符串

    • pattern: 匹配模式

    • init: 可选参数,指定匹配的起始位置

  • 返回值:

    • 如果匹配成功,则返回匹配的字符串

    • 如果匹配失败,则返回 nil

  • 例子:

    1local s = "hello world"
    2local m = string.match(s, "hello")
    3print(m) -- hello
    

string.gsub 替换匹配的字符串

string.gsub(s, pattern, repl, n)

  • 参数:

    • s: 要匹配的字符串

    • pattern: 匹配模式

    • repl: 替换字符串

    • n: 可选参数,指定替换的次数

  • 返回值:

    • 返回替换后的字符串和替换的次数
  • 例子:

    1local s = "hello world"
    2local new_s, n = string.gsub(s, "hello", "hi")
    3
    4print(new_s) -- hi world
    5print(n) -- 1
    

string.gmatch 迭代匹配的字符串

string.gmatch(s, pattern)

  • 参数:

    • s: 要匹配的字符串

    • pattern: 匹配模式

  • 返回值:

    • 返回一个迭代器函数,每次调用迭代器函数,返回一个匹配的字符串
  • 例子:

    1local s = "The quick brown fox jumps over the lazy dog"
    2for word in string.gmatch(s, "%a+") do
    3    print(word)
    4end
    

ngx_re

ngx.re.split 分割字符串

res, err = ngx_re.split(subject, regex, options?, ctx?, max?, res?)

  • 参数:

    • subject: 要分割的字符串

    • regex: 分割的模式

    • options: 可选参数,分割的选项

    • ctx: 可选参数,分割的上下文

    • max: 可选参数,分割的最大次数

    • res: 可选参数,分割的结果

  • 返回值:

    • 返回一个 table,包含分割后的字符串
  • 例子:

    1local ngx_re = require "ngx.re"
    2
    3local s = "a b  c   d    e"
    4local t = ngx_re.split(s, "\\s+") -- 分割空白字符
    5for i, v in ipairs(t) do
    6    ngx.say(i, ": ", v)
    7end
    
  • 输出:

    11: a
    22: b
    33: c
    44: d
    55: e
    
  • 例子:

    1local s = "a,b,c,d,e"
    2local t = ngx.re.split(s, ",", "jo") -- 分割逗号,且保留分割符
    3for _, v in ipairs(t) do
    4    print(v)
    5end
    

例子

  1. 匹配所有以字母 a 结尾的单词:

    %a+a

  2. 匹配所有以字母 a 开头的单词:

    a%a+

  3. 匹配所有包含字母 a 的单词:

    %a*a%a*

  4. 匹配所有三个字母的单词:

    %a{3}

  5. 匹配八进制数:

    [0-7]+

  6. 匹配十六进制数:

    0[xX][0-9a-fA-F]+

  7. [==[(?<!%)(%[a-z_]+)]==]

    解析:

    • [==[]==] 是字符的开始和结束标记,则内部的字符串字面量不需要转义。

    • 这里 (?<!%) 是一个 lookbehind 断言,表示匹配的字符串前面不是 %

    • %[a-z_]+ 表示匹配以 % 开头的,由字母和下划线组成的字符串。

    因此这个正则表达式的作用是匹配以 % 开头的,由字母和下划线组成的字符串。

    例如:%abc%_%_abc%_abc123 都是匹配的。而 %%abc 不会匹配。