匹配嵌套的构造(较复杂)

如果还不明白正则表达式中(?:)的使用,请看:http://www.knowsky.com/297.html



正则表达式的终极能力 - 递归

今天在QQ问liuzhi如何写一个匹配递归式的正则表达式时,没想到那家伙居然就回答“递归消除”,让我去看编译原理的书。(nnd,他肯定想到正则表达式的实现去了...)

找遍了正则表达式的语法都没发现和递归有关或者可以间接用来实现递归的,不过今天在硬盘找到一个电子书(只有一章),居然有讲解了这个。窃喜,记录之。

例子是:

\((?>[^()]+|\((?)|\)(?<-DEPTH>))*(?(DEPTH)(?!))\)

这个是匹配有效的最多括号的语法,比如:

before (nope (yes (here) okay) after

匹配到的是:(yes (here) okay)

简单翻译了下这个文档:

匹配嵌套的构造
微软公司已经包含了一个有趣的创新来匹配稳定的构造(历史上,这是正则表达式所做不到的)。这并不容易掌握 — 尽管这节较短,但是注意,它非常的晦涩难懂。
从一个例子开始可能更简单一些,所以我用这段代码作为开始:
Regex r = new Regex(@"\((?>[^()]+|\((?<DEPTH>)|\)(?<-DEPTH>))*(?(DEPTH)(?!))\)");
这能匹配到首个完全配对的括号组,比如"before (nope (yes (here) okay) after"里面的"(yes (here) okay)"。注意第一个左括号没有被匹配到,因为没有和它匹配的右括号。
下面是它如何运作的概览:
1、在每个"("被匹配到的时候,"(?<DEPTH>)"在这里加上一,告诉正则表达式系统当前括号嵌套的深度( 正则表达式开头的"\("不包括在这里)。
2、在每个")"被匹配到的时候,"(?<-DEPTH>)"从深度值内减一。
3、"(?(DEPTH)(?!))"保证在匹配最后一个右括号之前深度为零。
它能工作的原因在于引擎的回逆堆栈保存了匹配成功的组的轨迹。"(?<DEPTH>)"不过是一个带有名称的分组构造,它将总是匹配成功(不匹配任何东西)。而由于它被紧接着放在"\("之后,它的成功匹配(仍然在堆栈上直到被移除)被用于左括号的计数。
译注:还有一种写法是"(?<DEPTH>\()",我个人比较喜欢这种形式,而不是"\((?<DEPTH>)"。后面的"\)(?<-DEPTH>)"也是一样。
这样,匹配成功了的名为"DEPTH"的分组的计数在回逆堆栈上被建立起来。而当找到右括号的时候我们还希望从深度值减一,这是由.NET特别的语法构造 "(?<-DEPTH>)"实现的,它将从堆栈上移除最近匹配的"DEPTH"分组。如果堆栈上已经没有记录,"(?<- DEPTH>)"分组匹配失败,从而防止了正则表达式系统匹配多余的右括号。
最后,"(?(DEPTH)(?!))"是一个用于"(?!)"的断言,如果"DEPTH"分组到目前为止还是成功的话。如果当我们匹配到这里时还是成功 的,这里有个未配对的左括号还没有被"(?<-DEPTH>)"移除。在这种情况,我们希望停止匹配(我们不希望匹配一个未配对的括号),所 以我们使用"(?!)",它是一个“零宽度负预测先行断言”,仅当子表达式不在此位置的右侧匹配时才继续匹配。
这就是在.NET的正则表达式实现中匹配嵌套结构的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/550001.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XAF Excel数据导入模块使用说明与源码

我实现了XAF项目中Excel数据的导入&#xff0c;使用Devexpress 新出的spreadsheet控件&#xff0c;可能也不新了吧:D 好&#xff0c;先看一下效果图&#xff1a;下图是Web版本的。 下面是win版&#xff1a; 功能说明&#xff1a; 支持从Excel任意版本导入数据&#xff0c;可以使…

ASP注入漏洞基础教程(二)

进 阶 篇 在入门篇&#xff0c;我们学会了&#xff33;&#xff31;&#xff2c;注入的判断方法&#xff0c;但真正要拿到网站的保密内容&#xff0c;是远远不够的。接下来&#xff0c;我们就继续学习如何从数据库中获取想要获得的内容&#xff0c;首先&#xff0c;我们先看看&…

java日期用什么属性_java日期以及使用Java反射机制遍历实体类的属性和类型

fmt:formatDate 的输出格式 fmt关于时间格式的输出2004-5-31 23:59:592004-4-123:59:59JSTL标签fmt:formatDate引起的中文乱码问题解决方案解决方法&#xff1a;在后面写上一句&#xff1a;**************************************************Field[] fieldsIssue.class.getDe…

linux 内存清理/释放命令

1.清理前内存使用情况 free -m2.开始清理 echo 1 > /proc/sys/vm/drop_caches3.清理后内存使用情况 free -m4.完成!查看内存条数命令&#xff1a; dmidecode | grep -A16 "Memory Device$" # sync# echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys…

dotnet程序优化心得(三)

&#xff08;4&#xff09;继续优化――用空间换取时间 现在对每一个字符&#xff0c;都要用get_Item(object key)方法过一遍&#xff0c;可这个乖乖方法那么长&#xff0c;肯定太耗时间了&#xff0c;能不能用更简单的手段呢&#xff1f;改Hashtable&#xff1f;哇&#xff0c…

java网页解析包_java 网页解析工具包 Jsoup

Jsoup是一个非常好的解析网页的包&#xff0c;用java开发的&#xff0c;提供了类似DOM&#xff0c;CSS选择器的方式来查找和提取文档中的内容。相关资料如下&#xff1a;今天做了一个Jsoup解析网站的项目&#xff0c;使用Jsoup.connect(url).get()连接某网站时偶尔会出现java.n…

C++/CLI思辨录之传递托管堆地址

新的C特点平衡了把托管堆的地址传递到非托管代码的能力。早期我们遇到的最大问题是&#xff0c;在托管堆中的对象的位置是非静态的。垃圾收集器以变化的时间间隔移动对象。现在新的pin_ptr(别针型指针)的引入禁止垃圾收集器改变在堆上的对象的地址。下面代码展示了别针型指针的…

【Mininet】Mininet使用源码安装

实验参考&#xff1a; Mininet使用源码安装 实验步骤&#xff1a; 1. 更新软件&#xff08;用#sudo apt-get update与#sudo apt-get upgrade&#xff09;。 2. 从github上获取mininet源码&#xff08;#git clone git://github.com/mininet/mininet&#xff09;。 3. 获取完后&a…

java比较字符能用等于号码_Java字符串比较,==,等于,匹配,compareTo()之间的差异。...

的equals()方法将此字符串与指定的对象进行比较。当且仅当参数不为null并且是一个String对象&#xff0c;表示与此对象相同的字符序列时&#xff0c;结果为true。示例public class Sample{public static void main(String []args){String s1 "nhooo";String s2 &qu…

[SQL Server]用于压力测试和性能分析的两个支持实用工具[转]

微软有两个不提供支持服务的SQL Server压力测试和性能分析工具。具体看微软知识库&#xff1a;http://support.microsoft.com/?kbid887057 分别是&#xff1a;Read80Trace utility 和 OSTRESS utility 它们的下载地址请参看&#xff1a; http://www.microsoft.com/downloads…

【Mininet】Mininet可视化应用

实验参考&#xff1a; Mininet可视化应用 实验步骤&#xff1a; 1. 用命令启动mininet可视化界面&#xff08;#cd mininet/mininet/example #./miniedit.py&#xff09;&#xff0c;同时开启另一终端打开Opendaylight。 2. 用鼠标选择左侧的对应的网络组件&#xff0c;然后在空…

java 队列复制_复制一个文件夹里的文件到另一个目录下 (使用队列的方法实现)...

最近在由于准备实习&#xff0c;在学android&#xff0c;也会用到Java&#xff0c;所以想实现复制文件夹的功能&#xff0c;当然也参考了别人的代码。这里是我参考的网址&#xff1a;http://blog.csdn.net/etzmico/article/details/7786525/我发这个文章的主要目的是为了永久性…

【Mininet】Mininet命令延伸实验扩展

实验参考&#xff1a; Mininet命令延伸实验扩展 实验步骤&#xff1a; 1.用命令实现 #sudo mn --topo minimal #最小的网络拓扑&#xff0c;一个交换机下挂两个主机。 #sudo mn --topo linear,4 #每个交换机连接一个主机&#xff0c;交换机间相连接。本例&#xff1a;4个主机&a…

asp.net里导出excel表方法汇总

1、由dataset生成 public void CreateExcel(DataSet ds,string typeid,string FileName) { HttpResponse resp; resp Page.Response; resp.ContentEncoding System.Text.Encoding.GetEncoding("GB2312"); resp.AppendHeader("Content-Disposition", &quo…

java非检查性异常有哪些_Java异常处理-检查性异常、非检查性异常、Error

一、Java异常处理详解异常.png目录&#xff1a;1.java中异常的分类1.1 异常(Exception)1.1.1 运行时异常(RuntimeException)可以不需要捕获1.1.2 编译异常(IOException)编译器会提示要捕获&#xff0c;如果不进行捕获则编译器会报错1.2 错误(Error)3.java处理异常机制4.throw和…

【Mininet】基于Mininet测量路径的损耗率

实验参考&#xff1a; 基于Mininet测量路径的损耗率 SDN常用控制器安装部署之POX篇 实验步骤&#xff1a; 1. 在装有mininet的虚拟机中新建文件mymininet.py并编辑以下内容&#xff0c;这里要注意一点&#xff0c;文中的dp0与dp1须填POX安装的虚拟机的地址&#xff0c;由于本次…

HTML 标记一览

标记 类型 名称或意义 作用 备注文件标记<HTML> ● 文件宣告 让浏览器知道这是 HTML 文件 <HEAD> ● 开头 提供文件整体信息 <TITLE> ● 标题 定义文件标题&#xff0c;将显示于浏览器顶端 <BODY> ● 主体 设计文件格式及内容所在 排版标记<!--注解…

【Mininet】Mininet设置带宽之简单性能测试

实验参考&#xff1a; Mininet设置带宽之简单性能测试 实验步骤&#xff1a; 1. 进入mininet/custom目录下&#xff0c;通过vi mymininet1.py创建脚本并添加内容&#xff08;本实验通过python脚本自定义拓扑&#xff0c;创建包含一个交换机、四个主机的网络拓扑&#xff09;&am…

java 配置tocat_Tomcat安装配置及Eclipse配置详解

整个安装过程我们先学习安装jdk和配置然后是安装tomcat和配置&#xff0c;最后我们学习安装eclipse和配置以及web程序的使用和发布举例1. 安装jdk和配置(1)下载jdk安装包&#xff1a;(2)按照步骤点击下一步进行jdk软件的安装。(3)配置javajdk的环境变量**配置环境变量包括java_…

[CityLife]“背后的故事”---贫嘴曾志伟

受伤后&#xff0c;很久不曾看电视了&#xff0c;最晚打开电视机看了湖南卫视的一档节目: “背后的故事”---贫嘴曾志伟的幸福生活(上&#xff09;他个子矮小&#xff0c;却快乐豁达。父有名而不以父为名。有女&#xff0c;女娇却是 父以女骄。他讲自己曾经5块钱过了2周&#x…