API(六)工具类型之玩转正则表达式等常用SDK

  玩转正则表达式等常用API

在 OpenResty 中使用正则

①  正则

1、openresty存在'两套'正则表达式规范

 1) lua自身'独有'的正则规范   

 备注:大约有'5%~15%'性能损耗

 损耗原因:表达式'compile'成pattern,并不会被缓存,每次都会被重新'compile'编译

 2) nginx的符合'POSIX'规范'的PCRE'正则规范  --> 推荐并'强制'使用

ngx.re模块和lua正则匹配的区别

②  ngx.re API的来源

lua-resty-core 提供ngx.re.split      lua-nginx-module提供ngx.re API

涉及: 'match、find、sub、gsub、gmatch'、'split、opt'函数

match: '单次'正则匹配,同时也会'捕获'子表达式

gmatch:多次正则匹配 --> 以'迭代器'的方式

find:  同match,但返回的是'查找'到的位置索引

sub:   '单次'正则替换

gsub:  全局'global'正则替换

split: 正则'分割'

关注点: 函数的'参数'、'作用域'

③  ngx.re.match

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

关注: '入参含义'、'可选项'、'返回值'

补充: 参数subject和regex是'必须'的,而后三个options、ctx、res_table都可以'省略'

captures[n]是匹配的'子表达式';如果未找到匹配或者出错,那么captures就是nil,err 是错误信息

附加: captures '说明'

  1) captures 是'table'类型

  2) captures[0]存储匹配出的'完整'子字符串

  3) 其他'从1开始'的元素存储regex指定的'捕获'

常用: regex 'pattern' 用'变量'代替

1、基本'解读'

 1) 如果'有匹配'结果,返回'第一个'匹配的结果
 
 2) 如果'没有匹配'的结果,value=nil

 3) 如果出现'异常',value=nil,err为'异常'信息

说明: 以下'四个'官方案例,不使用'options'和''

2、regex 'pattern解读' --> 'PCRE'正则

nginx中使用的PCRE正则 

3、可选'options'参数解读

推荐: "oj" 参数  --> "双引号"

x: 允许在'模式中'加入任何数量的'空白'

补充: 'o'选项的解读

说明: 'u'选项的'案例'

4、可选'ctx'参数解读

5、可选'res_table'参数解读  --> "了解"

解读: 存储'所有匹配'的结果,相当于'返回值captures',有利于'重用内存'

res_table案例

④  ngx.re.find

1: 上下文  --> '思考:常用在哪个阶段?'

2: synax '语法'

关注点: 可选入参 'nth?'、返回值 'from、to、err'

备注: 其它'入参解读'参见 'ngx.re.match'函数讲解

3: 基本'解读'

 1) 如果'有匹配'结果,start、end表示'第一个匹配'的'起、始'索引位置

 细节点: 好好体回'第一个匹配'的含义

 2) 如果'没有'匹配的结果,start、end=nil

 3) 如果出现'异常',start、end=nil,err为'异常'描述信息

备注: 返回值根据'不同'的匹配结果,是'动态'的

4、应用'场景'

场景:当只需要判断'是否能匹配到'时推荐使用'find'而不是match方法

强调:re.find '没有创建'新字符串 的'性能'好于re.match ,'软waf防火墙'一般会使用're.find'

原因:因为该方法'不会'产生'新'的lua tables,'速度'更快

5、对可选入参'nth'的解读

⑤  ngx.re.gmatch

1: '基本解读'

 1) 语法格式:value, err = ngx.re.match(subject, pattern, options?)
 
 2) 返回'迭代器',可'遍历'输出'匹配'数据

 3) 如果出现'异常',value=nil,err为'异常'信息

2:案例'讲解'

⑥  ngx.re.sub

1:基本'解读'

 1) 语法格式:newStr, n, err = ngx.re.sub(subject, pattern, replace, options?)

 2) 功能:将'第一个匹配的字符串'替换为'replace',返回'替换后'的字符串'newstr'

 备注: '返回 n'表示替换的'次数 (0或者1)'

 附加: sub --> 'substitutes' --> '替换'

2: 案例'讲解'

案例1: 'replace'是'字符串'的形式

 1) replace中'$0'、'$1'、'${n}'的含义

 2) 只能使用'$'转义'$'获取'$'字面字符,不能使用'\'进行转义

案例2: 'replace'是'function'的形式,此时'match table'是'replace function'的入参

⑦  ngx.re.gsub

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

⑧  ngx.re.split

1: '导读'

2: 基本'语法'解读

细节:

  1) split是lua-resty-core 库的一部分,能够非常轻松地'切分'字符串

  2) 但它'没有内置'在ngx.re表内,必须'显式加载ngx.re模块'才能使用

   reqire("ngx.re").split  --> '显式加载'ngx.re模块,这里'不复用'
3: '案例1'讲解 --> 不同的'regex'分割形式

 形式1: regex --> "(,)"

 形式2: regex --> ""

4: '案例2'讲解 --> options为'nil',ctx含有'pos'字段

5:max '可选'参数解读 --> '参数5'

场景: 在'己知'可能的字串数量的时候可以'提前'结束匹配,提高'效率'

6:res '可选'参数解读 --> '参数6'  --> '了解即可'

⑨  require "ngx.re".opt

相关参考

⑪  openresty的正则指令

1: 'lua_regex_match_limit'  --> 限制'回溯'次数

lua_regex_match_limit

如何彻底避免正则表达式的灾难性回溯     nginx的正则回溯和灾难性回溯

lua_regex_cache_max_entries 

2: 'lua_regex_cache_max_entries'  --> 正则'缓存'

⑩  正则转义

1、在'*_by_lua_block'中使用:

1)  需要\\\\d表示\d,因为ngxin.conf会将'\\\\d'解析成\\d,再在lua中解析成\d

2) 使用[[...]],在[[...]]里可以'直接被lua用',像这样[[\\d]]

2、在'*_by_lua_file'中使用:

1) \\d被lua解析一次为\d

2) 用[[...]],直接使用'[[\d]]'

备注:其他'转义字符'同理 

案例:ngx.re.match(str,[[\w+z]],'ijo') --> 忽略大小写,'编译并缓存'

openresty编程最佳实践   令牌桶算法的限流实例   正则 [[]]案例

OpenResty动态反向代理域名的实践    

lua自身的正则表达式

openresty最佳实践    注解5

nginx'内存'泄露: gdb、nmmap、'火焰图'等
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将日期字符串 "20240629" 转换为正则表达式的步骤如下: 1. **解析年份、月份和日期**:首先,我们需要从输入字符串中识别出年份、月份和日期部分。 - **年份**:“2024”是一个四位数,通常用于表示年份,因此我们可以直接匹配它。 - **月份**:“06”,这是一个两位数的格式,代表月份数字,通常月份范围从 '01' 到 '12'。 - **日期**:“29”,同样也是一个两位数,用于表示日数。 2. **创建正则表达式模式**:结合上述分析,我们构建的正则表达式应能匹配上述所有元素。为了使模式更具通用性并适应各种日期格式,我们可以考虑允许任意的年份长度(通常为四位),月份长度为两位数字,并对日期进行更宽松的限制。 3. **实际的正则表达式**:基于上述理解,可以构建如下的正则表达式模式: ```regex ^\d{4}(\d{1,2})?(\d{1,2})$ ``` 这里: - `^\d{4}` 匹配开头的四位数字(即年份)。 - `(\d{1,2})?` 是一个非捕获组,其中 `\d{1,2}` 表示匹配一位或多至两位的数字(这可以覆盖 '01' 到 '12' 或 '01' 到 '31' 的情况)。这里的问号 `?` 意味着这部分不是必需的,允许存在零值的情况(例如,在一些年份末尾的日期格式中可能出现 '2024/' 后跟着月份而没有日期)。 - `$` 标记表示整个字符串的结束,确保只有完全匹配的部分会被接受。 通过这个正则表达式,你可以验证一个字符串是否恰好由四位年份、一个空位(可选)、一个两位数的月份、另一个空位(可选)、以及另一个两位数的日组成。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值