2025年nginx(五十三)nginx中使用的PCRE正则

nginx(五十三)nginx中使用的PCRE正则一 pcre 正则语法 说明 1 从 在 nginx 中 使用符合 PCRE 风格 正则的角度上 学习 2 部分 案例 比较冷门 不具有 实际 生产意义 PCRE 汇总 元字符 说明 通过 转义 使一些

大家好,我是讯享网,很高兴认识大家。

一   pcre 正则语法

说明: 1)从'在nginx中'使用符合'PCRE风格'正则的角度上'学习' 2) 部分'案例'比较冷门,不具有'实际'生产意义

讯享网

PCRE汇总 

①  元字符

讯享网说明: 通过'\'转义,使一些'字符'具有'特殊'的含义 正则中'需要\转义'的场景: 1) * . ? + $ ^ [] () {} | \ / --> 加\将'元字符'转义为'字面意思' 2) 字面字符 -->加\将'普通字符'转义为'特殊含义'


讯享网

②   字符组(

说明: PCRE也支持'POSIX'风格的字符组 等价: \D、[^0-9]、[[:^digit:]] 三者'等价'

讯享网小细节: 1) nginx支持'POSIX'风格的正则"[[::]]" 2) '$server_name'获取的永远是'server_name'指令的'第一个'值

③  量词

难点: '贪婪'和'非贪婪'

④  分组补获

讯享网'分组'常见'三种'形式: 1、(pattern) -->'普通分组',捕获的字符串会'被缓存起来'以供后续使用 2、(?<name>pattern) -->'命名分组','可读性'好,相当于创建了一个'新'变量,'推荐' 3、(?:pattern1|pattern2) -->'非补获分组',模式匹配上,但是'没分组',后面'无法引用' +++++++++++++++++++++++++ "分割线" +++++++++++++++++++++++++ '对()中补获'和'引用的方式': 1、$1,$2,$3,$4,$9,有些地方使用\1,\2,\3,...\9 备注: sed中使用'&'表示所有匹配,perl中则使用'$&' 重点: nginx在'模式'中使用'\1'之类,在后续'其它补获'的地方用类似'${1}' 2、 \g1,\g2,\g3 或 \g{1},\g{2},\g{3} 备注: 其中$1,$2, ...用于'正则外面',而"\g1", "\g2", ... 用于'正则内部' 3、引用'号'要与对应'()'相适配

nginx对捕获分组的支持

⑤  锚点和零长度断言

特点: '不会'匹配实际的'内容(content)',而是'寻找'文本的'位置(position)'

⑥  反向引用

讯享网强调: 这里反向引用在'pattern(查找)'中使用 1)'数字'引用 -->'\1' -->对应'第一个()'分组 2)'命名'引用 -->'\k<name>' 重点: nginx中如何在'非pattern'中引用补获的内容 --> '$1' 或 以'变量${name}'的形式 补充: nginx中'无法'获取'模式匹配(类似 grep -o)'的内容,只能获取'分组'的内容 遗留: 'sed、awk'或'编程语言中'的'替换'引用怎么做的呢?

⑦   多选结构

细节点: 一般通过'(a|b|c)<=>[a-c]'或'(str1|str2|str3)字符串分组'两种形式使用

⑧  正则注释

讯享网形式: (?#正则注释) -->'了解即可' 说明: 可以通过'nginx.conf'中的'#'注释进行解读

⑨  环视匹配

环视: 这个词从字面理解就是确定'周围环境' 环视匹配: 别名"预搜索",他只是'约束','不参与'匹配结果的'生成' 重点:要找到'参考'的'坐标原点',才能'更好'的理解'环视'匹配 本质:环视'不匹配'任何'字符',只匹配文本中的特定'位置'

 环视匹配的案例参考  

讯享网说明: 又叫做'assert',断言只是'条件',帮你找到'真正需要'的字符串,本身并'不会'匹配 补充: 问号'?'就是在说这是一个'非捕获组',这个组'没有编号',不能用来后向引用,只能'当做断言'

  

++++++++++ "体会()和(?:)的区别" ++++++++++ 说明: curl -w '\n' -H 'Host:ceishi.wzj.com' http://172.25.2.100:8000/6/aa 备注: \1和$1'使用'的是'(\w)',而不是'(?:\d)'

讯享网++++++++++ "体会(?:)和(?=)的区别" ++++++++++ 共同点: (?:pattern) 与 (?=pattern)都'匹配分组',但'不会'把分组放到'匹配结果'中 差异点: 1)(?:pattern) 匹配得到的结果'包含pattern',(?=pattern) 则'不包含' 2) '消耗'字符 (?:pattern) 消耗字符,下一字符匹配会从'已匹配后的位置'开始 (?=pattern) 不消耗字符,下一字符匹配会从预查之前的位置开始.只预查,'不移动'匹配指针

(?:pattern) 和 (?=pattern) 的案例理解

++++++++++++++ "grep的题外话" ++++++++++++++ 1) 类似用(),然后补获$1的值,细细体会'不用sed awk cut perl',只用'grep' 2) 'GUN' grep 才支持-P选项,BSD不支持,并且是'实验特性' 3) grep 搜索到的模式以'特殊颜色'标识;但是默认以行为单位显示,加上'-o'只匹配搜到的模式字符串 4) grep 匹配utf8'中文字符' --> grep -Po "[\80-\xFF]"

讯享网重点: '逆向'环视的表达式只能是'固定'长度

  

PCRE正则的if判断   (?(condition)true-pattern|false-pattern)

⑩  正则选项

作用域: 为模式'随后的部分'或'未结束的模式分组'设置选项J/i/m/s/x/U'开关'

讯享网1)(?i):不区分大小写,可使用'(?-i)取消该'模式 -->'重点掌握' 场景1: "(?i)wzj(?-i)Wzj"只对'中间的wzj'进行不区分大小写的匹配 场景2: 由于(?i)'遇到闭括号'就失效,可以将需要'不区分大小写匹配的部分'写入'分组括号'中 例如: "((?i)abc)cdB"、(?:(?i)abc)cdB=(?i:abc)cdB 2)(?x):extend模式,将'忽略'pattern中多个'连续空格'和'注释符'到行尾的字符 理想: [1]、采用了'x模式'修正符,可以在用模式中加入'空格对符式'进行'格式上的分隔 [2]、'并'分行'表示而不影响模式的解析 实际: nginx'不支持'这种'PCRE'正则 3)(?m):'multiline'多行模式,改变'^'和'$'的匹配模式 -->'了解' [1]、默认模式下,它们分别匹配字符串'首部'和'尾部' [2]、此模式下: (1)^将匹配字符串'首部'和'换行';若要'仅'匹配字符串首部,使用\A (2)$将匹配字符串'尾部'、'换行符'和换行符前的'空'字符 -->若要仅匹配字符串尾部和行尾,使用\Z,若要仅匹配字符串尾部,使用\z 4)(?s):(singleline或dotall)单行模式,改变"."的匹配模式, [1]、默认模式下,点"."无法匹配换行符,dotall模式下可以 5)(?U):lazy匹配模式;'默认是greedy匹配' 6)The (?J) internal option setting changes the local PCRE_DUPNAMES option. --> Allow duplicate'复制' names for subpatterns.

说明: 'reload'没有报错,请求的时候符合预期,说明'nginx'中的PCRE支持'选项' 场景: url中只有'部分'字符串'区分'大小写

⑪  强转

讯享网强制'字面'解释:\Q...\E;该序列将'其中间的所有字符'强制解释为'字面'符号,强制性极强

  

⑫  重置位置

作用: '\K' 用于'重置匹配的位置',\K '左边'的所有东西被"退回"且不作为'pattern'的匹配部分 细节: '\K' 的使用'不会干预到子组内'的内容,还是会'补获' 效果: 有点'删除'的意味 

⑬  条件子模式

讯享网条件子模式中的'条件'有三种: 1)一种是'前向匹配断言'结果 --> '常见' (?=assert) 、(?!assert) --> '环视匹配' 备:断言可以是'肯定'或'否定'的前身或后向断言 2)另一种是看'是否捕获'一个前面'提供的子模式' -->'命名'补获和'普通编号'补获 备: 如果在'表示条件的圆括号'里的内容'是一个数字',表示此数字代表的子模式被成功匹配时条件为真 3)条件的圆括号内是一个"R"字符 --> "难点",不常用 备:表示在这个模式或子模式'被递归调用'时条件为真;在递归调用的'顶层',这个条件为'假'

  

说明: 了解'nginx'可以这样做,但是一般不会这么'复杂'

讯享网++++++++ '案例2' ++++++++

后视断言必须是固定长度

理解: 就是说(?<=)和(?<!)这种'lookbehind里'不能有'+、*'这样的'不定长度'的量词

lookbehind assertion is not fixed length

⑭  如何构造正则表达式

讯享网如何在nginx中'构造'正确正则表达式 1)构造正则表达式的方法和'创建数学表达式'的方法一样 2) 也就是用'多种元字符'与'操作符'将小的表达式'结合'在一起来创建更大的表达式 3) 正则表达式可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合 4) 正则表达式的'语法校验'

⑮  固化分组

1) 固化分组的'格式': '(?>...)' 需求: 能否让'([1-9])+'匹配一旦成功,'不进行回溯'呢? --> 这就用到了我们上面说的"固化分组" 特点: [1]、当此部分表达式匹配完毕,开始匹配括号'外'面的部分时,括号'内'所有'备用'状态都会被放弃 [2]、也就是说,在固化分组'匹配结束'时,它'已经匹配的文本'已经'固化'为一个单元 [3]、只能作为'整体'而'保留'或'放弃' [4]、括号内的'子表达式中'未尝试过的备用状态都不复存在了,所以回溯永远也不能选择其中的状态 [5]、至少是,当此‘结构匹配完成‘时,"锁定(locked in)"在其中的状态

固化分组的参考

二    nginx中的正则

pcre和正则表达式的误点

nginx模块开发中使用PCRE正则表达式匹配

nginx中正则中对.、{、}等字符处理

①  nginx中的pcre版本

讯享网1)nginx对'PCRE'风格正则的'支持'程度? 2)源码编译'--with-pcre'和rpm安装使用'pcre'版本 3)nginx的和pcre的'版本适配'问题 注意:nginx'不支持pcre2'版本 --> 报错 fatal error: 'pcre.h' file not found 

②  nginx哪些指令支持pcre正则

1)map -->'~'要与'对应字符串'紧连 2)server_name '域名匹配' -->因为可能有多个域名,所以'~'要与'对应正则域名紧连',不能有空格 细节点: 最好不要使用'$server_name'做'80-->443'跳转;因为'正则'和'多域名'的原因 3)rewrite '重定向' --> '~ 有空格' 思考1: nginx在'rewrite跳转'过程中,哪些信息会'丢失'?是否可以'修改'信息? 思考2: rewrite 在跳转后加上'锚点#' 4)if '判断' --> '~ 有空格' 5)location --> 'uri匹配'

③   nginx中哪些符号表示是正则匹配

讯享网1)`~` 正则'区分大小写'匹配 2)`~*` 正则'不区分大小写'匹配 3)`!~` 正则区分大小写'匹配失败'的时候 -->'反向' 4)`!~*` 正则不区分大小写'匹配失败'的时候 注意:^~ '不是'正则 思考: 正则中哪些字符需要'转义'? [1]、'特殊'元字符转化为'普通'字符 -->例如:'\.、\\' 常见:'()、{}、|、\、.、*' [2]、'普通'的字符转化为'特殊'含义 -->例如:'\d、\1'

④   pcretest命令测试正则语法

pcregrep命令

grep -Pzo '<==>' 'pcregrep'

pcre正则在线测试

④ pcre_jit指令优化nginx正则

讯享网1) 启用'前提条件' [1]、pcre库的版本'pcre8.20+' [2]、nginx编译时'添加参数': --with-pcre --with-pcre-jit 备注: 取决于nginx'源码编译'时,使用系统的'pcre'库还是'源码编译pcre库' 2) nginx'使用'方式 http { pcre_jit on; } 备注: main 全局域 mginx 的'根级别指令'区域

 nginx调优之启用PCRE JIT以加速正则表达式的处理  PCRE性能优化 

小讯
上一篇 2025-03-25 22:22
下一篇 2025-02-19 09:30

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/45875.html