在常见的文本匹配场景上,经常会需要用到一些像HTML这样的嵌套标签类型的文本匹配,经过多翻折腾,拼凑出了这样的一条语句

(<([\w]+)>((?1)|[\w\s])*</\2>)

如何理解?

要解析上面的语句是如何运行的,先来了解一下PCRE的反向分组引用机制

(?n)

以括号为单元,紧贴左括号以?号开始,接着引用分组的序号数字,这是反向引用分组的语法

例如,\[([\w]+)-(?1)\]将会匹配像[9-3],[9-9]这样的结构,因为(?1)引用了第一个括号的表达式也就是([\w]+),用来匹配接下来的字符

如何得知分组的序号数字?

例如,\[([\w]+(\s)?)-(.*)\]

分组1将会是([\w]+(\s)?),

而分组2将会是(\s),

想必你已经知道分组3将会是(.*)了。

接下来介绍一个另外的反向分组引用机制

'\n'

以反斜杠开头,接着引用分组的序号数字,这是反向引用分组结果的语法

和(?n)有什么不同?

稍微更改一下刚才的语句就知道了,

现在把\[([\w]+)-(?1)\]更改为\[([\w]+)-\1\],再来匹配一下[9-3],[9-9],没错,现在只能匹配到[9-9]这样的结构了,因为\1引用了第一个括号的表达式也就是([\w]+)匹配的结果用来匹配接下来的字符,而不是直接引用执行

现在回头看看片头给出的语句,已经不难理解了

来解析一番:

假设有以下一条HTML片段

<p> i am <i> genius </i> , do you agree? </p> <p> absulutely not </p>

引擎从第一个分组开始匹配(也就是整一条表达式)

(<)

(然后p,没有更多了,没关系,+不要求更多,继续往下)

(>,一切都很顺利)

(空字符,匹配了[\w\s],继续。。。)

。。。

当来到了下一个标签<i>,转折点在这里,<的出现,让原先一路往右的语句引用了整个式子,此时语句会率先执行向后引用的语句,然后等待匹配结果,当向后引用的语句再次遇到引用怎么办?显然,它的做法也会和它上一层的语句一样,直到匹配没有被继续引用,并且执行到了结尾,所有向后引用的公式会一层层的返回,这个情形类属于函数上的递归算法

改进一下就可以支持tag属性和img这种没有结束tag的标签

(<(div|p|table|tbody|tr|td|a)[\s\w='":;./#!]*>(?:(?1)|[^<]|<(?:img)\s+[^>]+)*<\/\2>)

支持更多的无结束标签tag

(<(?:(div|p|table|tbody|tr|td|a)|(img|meta|link))([\s\w='":;./#!-,]*)>(?(2)((?1)|[^<]|<(?3)(?4)[/]?>)*<\/\2>))

全程用到了哪些语法

#分组捕获
”(?n)“
#反向引用结果
”\n“
#消除分组捕获和反向引用,运用这种语法括号中的表达式将只匹配而不会被捕获,例如(?:[a])([b])\1,\1捕获的分组会是([b])
"(?:)"
#if 流程控制,运用这种语法将会判断先前出现的分组n是否触发了匹配,如果是则启用当前括号分组的规则,例如(a)?(?(1)bb)c,只有当(a)?成功匹配了,接下来才会匹配bb
"(reg)(?(n)trueReg|falseReg)"

备注:

JavaScript并不支持分组捕获(?n),但是支持反向引用结果

[正则表达式]PCRE反向分组引用的更多相关文章

  1. [正则表达式]PCRE反向分组引用(语法)

    正则表达式中,凡出现圆括号(),括号中的匹配内容就会被认为是一个分组: 根据括号从左边出现的顺序命名分组代号,分组代号由1到n(代号0通常被一些语言用来引用整个表达式匹配的结果,即使这个表达式没有分组 ...

  2. Django url配置 正则表达式详解 分组命名匹配 命名URL 别名 和URL反向解析 命名空间模式

    Django基础二之URL路由系统 本节目录 一 URL配置 二 正则表达式详解 三 分组命名匹配 四 命名URL(别名)和URL反向解析 五 命名空间模式 一 URL配置 Django 1.11版本 ...

  3. PHP 正则表达式(PCRE)

    PHP 正则表达式(PCRE) 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将匹配的子串做替换或者从某个串中取出符合某个条件的子串 ...

  4. Python 正则表达式 利用括号分组

    如果想把区号从匹配的电话号码中分离,可以添加括号在正则表达式中创建分组,再使用group()方法,从一个分组中获取匹配的文本 正则表达式字符串中,第一个括号是第一组,第二个括号是第二组.向group( ...

  5. python正则表达式中的分组 group

    维基百科:http://wiki.ubuntu.org.cn/Python%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%93%8D%E4%BD%9C ...

  6. [正则表达式]PCRE环视功能

    设想一下这个问题,假设为了方便长串数字的阅读性,需要为其添加逗号作为分隔,需要怎么做呢? 2569836495 => 2,569,836,495 正则表达式的匹配通常是从左往右的,这导致无法使用 ...

  7. 廖雪峰Java9正则表达式-2正则表达式进阶-3分组匹配

    1.使用括号可以提取字符串 不加括号匹配电话号码 匹配成功后,如何提取想要的字符串? 使用(...)可以分组:"^(\d{3,4})\-(\d{6,8})$" 2.String.m ...

  8. java中的正则表达式捕获组与引用的概念

    今天群里有个人问,怎样用增则表达式匹配三角形的三边,其实只是要匹配三个数字而已,如 301 402 503 开始认为很简单,我就写了一个   "(([1-9]\\d?)\\s){2}$2&q ...

  9. 正则表达式-python-无捕获分组与分支选择

    无捕获分组 当你要将一部分规则作为一个整体对它进行某些操作,比如指定其重复次数时,你需要将这部分规则用 (?:) 把它包围起来. 分支条件 在正则表达式中,分支条件是一个很常用的条件. 满足条件A 或 ...

随机推荐

  1. [CareerCup] 5.7 Find Missing Integer 查找丢失的数

    5.7 An array A contains all the integers from 0 to n, except for one number which is missing. In thi ...

  2. 基于C/S架构的3D对战网络游戏C++框架 _02系统设计(总体设计、概要设计)

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  3. SQLite剖析之临时文件、内存数据库

    一.7种临时文件    SQLite中,一个数据库由单个磁盘文件构成,简化了SQLite的使用,因为移动或备份数据库只要拷贝单个文件即可.这也使得SQLite适合用作应用程序文件格式.但是,当在单个文 ...

  4. servlet的四个作用域

    作用域规定的是变量的有效期限,servlet有四个作用域对象,这里只说三个: 一. request作用域: 1.作用范围: 就是指从http请求发起,到服务器处理结束,返回响应的整个过程.在这个过程中 ...

  5. 风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,

    转自:http://www.cnblogs.com/ranranblog/p/5845010.html 风口之下,猪都能飞.当今中国股市牛市,真可谓“错过等七年”. 给你一个回顾历史的机会,已知一支股 ...

  6. Java 中 手动抛出异常: throw new Exception("错误信息") 错误信息的获得

    当然需要先用try catch捕获,但注意new Exception("")括号里的字符串其实是异常原因,所以获取是要用ex.getCause().getMessage() int ...

  7. Redis 学习(二)

    Redis可以存储以下5种数据类型 1. String 字符串 整数 浮点 2. List   一个链表 3. Set  无序收集器 4. Hash  无序散列表 5. Zset   有序集合

  8. delphi 并发取数据库id问题

    这段时间有个项目id频繁出现 id冲突的问题 一真找不到原因 后来想到了个办法 在新建取id时先把到到的id保存起来 上代码 望大神指点下 /// <summary> /// 到表中的最大 ...

  9. Android基础总结(一)

    Android项目的目录结构 Activity:应用被打开时显示的界面 src:项目代码 R.java:项目中所有资源文件的资源id Android.jar:Android的jar包,导入此包方可使用 ...

  10. BZOJ4614 [Wf2016]Oil

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...