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

一   pcre 正则语法

说明: 

  1)从'在nginx中'使用符合'PCRE风格'正则的角度上'学习'

  2) 部分'案例'比较冷门,不具有'实际'生产意义

PCRE汇总 

①  元字符

说明: 通过'\'转义,使一些'字符'具有'特殊'的含义

正则中'需要\转义'的场景: 

  1) * . ? + $ ^ [] () {} | \ /  --> 加\将'元字符'转义为'字面意思'

  2) 字面字符                      -->加\将'普通字符'转义为'特殊含义'

nginx(五十三)nginx中使用的PCRE正则_第1张图片

②   字符组(

说明: PCRE也支持'POSIX'风格的字符组

等价: \D、[^0-9]、[[:^digit:]]  三者'等价'

nginx(五十三)nginx中使用的PCRE正则_第2张图片

nginx(五十三)nginx中使用的PCRE正则_第3张图片

小细节: 

  1) nginx支持'POSIX'风格的正则"[[::]]"

  2) '$server_name'获取的永远是'server_name'指令的'第一个'值

③  量词

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

nginx(五十三)nginx中使用的PCRE正则_第4张图片

nginx(五十三)nginx中使用的PCRE正则_第5张图片

④  分组补获

'分组'常见'三种'形式: 

  1、(pattern)               -->'普通分组',捕获的字符串会'被缓存起来'以供后续使用

  2、(?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(五十三)nginx中使用的PCRE正则_第6张图片

nginx对捕获分组的支持

nginx(五十三)nginx中使用的PCRE正则_第7张图片

⑤  锚点和零长度断言

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

nginx(五十三)nginx中使用的PCRE正则_第8张图片

⑥  反向引用

强调: 这里反向引用在'pattern(查找)'中使用

1)'数字'引用 -->'\1' -->对应'第一个()'分组

2)'命名'引用 -->'\k'

重点: nginx中如何在'非pattern'中引用补获的内容  --> '$1' 或 以'变量${name}'的形式

补充: nginx中'无法'获取'模式匹配(类似 grep -o)'的内容,只能获取'分组'的内容

遗留: 'sed、awk'或'编程语言中'的'替换'引用怎么做的呢?

nginx(五十三)nginx中使用的PCRE正则_第9张图片

nginx(五十三)nginx中使用的PCRE正则_第10张图片

⑦   多选结构

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

⑧  正则注释

形式: (?#正则注释)  -->'了解即可'

说明: 可以通过'nginx.conf'中的'#'注释进行解读

nginx(五十三)nginx中使用的PCRE正则_第11张图片

⑨  环视匹配

环视: 这个词从字面理解就是确定'周围环境'

环视匹配: 别名"预搜索",他只是'约束','不参与'匹配结果的'生成'

重点:要找到'参考'的'坐标原点',才能'更好'的理解'环视'匹配

本质:环视'不匹配'任何'字符',只匹配文本中的特定'位置'

 环视匹配的案例参考  

nginx(五十三)nginx中使用的PCRE正则_第12张图片

说明: 又叫做'assert',断言只是'条件',帮你找到'真正需要'的字符串,本身并'不会'匹配

补充: 问号'?'就是在说这是一个'非捕获组',这个组'没有编号',不能用来后向引用,只能'当做断言'

  

nginx(五十三)nginx中使用的PCRE正则_第13张图片

++++++++++ "体会()和(?:)的区别" ++++++++++

说明: curl -w '\n' -H 'Host:ceishi.wzj.com' http://172.25.2.100:8000/6/aa

备注: \1和$1'使用'的是'(\w)',而不是'(?:\d)'

nginx(五十三)nginx中使用的PCRE正则_第14张图片

++++++++++ "体会(?:)和(?=)的区别" ++++++++++

共同点: (?: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]"

nginx(五十三)nginx中使用的PCRE正则_第15张图片

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

nginx(五十三)nginx中使用的PCRE正则_第16张图片  

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

⑩  正则选项

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

nginx(五十三)nginx中使用的PCRE正则_第17张图片

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.

nginx(五十三)nginx中使用的PCRE正则_第18张图片

说明: 'reload'没有报错,请求的时候符合预期,说明'nginx'中的PCRE支持'选项'

场景: url中只有'部分'字符串'区分'大小写

⑪  强转

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

  

⑫  重置位置

作用: '\K' 用于'重置匹配的位置',\K '左边'的所有东西被"退回"且不作为'pattern'的匹配部分

细节: '\K' 的使用'不会干预到子组内'的内容,还是会'补获'

效果: 有点'删除'的意味

⑬  条件子模式

条件子模式中的'条件'有三种:

 1)一种是'前向匹配断言'结果  --> '常见' (?=assert) 、(?!assert) --> '环视匹配'

 备:断言可以是'肯定'或'否定'的前身或后向断言

 2)另一种是看'是否捕获'一个前面'提供的子模式' -->'命名'补获和'普通编号'补获

 备: 如果在'表示条件的圆括号'里的内容'是一个数字',表示此数字代表的子模式被成功匹配时条件为真

 3)条件的圆括号内是一个"R"字符 --> "难点",不常用

 备:表示在这个模式或子模式'被递归调用'时条件为真;在递归调用的'顶层',这个条件为'假'

nginx(五十三)nginx中使用的PCRE正则_第19张图片

  

nginx(五十三)nginx中使用的PCRE正则_第20张图片

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

nginx(五十三)nginx中使用的PCRE正则_第21张图片

++++++++  '案例2'  ++++++++

后视断言必须是固定长度

理解: 就是说(?<=)和(?

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(五十三)nginx中使用的PCRE正则_第22张图片

nginx(五十三)nginx中使用的PCRE正则_第23张图片

②  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命令测试正则语法

nginx(五十三)nginx中使用的PCRE正则_第24张图片

pcregrep命令

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

pcre正则在线测试

④ pcre_jit指令优化nginx正则

nginx(五十三)nginx中使用的PCRE正则_第25张图片

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性能优化 

你可能感兴趣的:(nginx,nginx,正则)