当前位置: 首页 > 编程日记 > 正文

DFA和NFA

1.历史:

引用

正则表达式萌芽于1940年代的神经生理学研究,由著名数学家Stephen Kleene第一个正式描述。具体地说,Kleene归纳了前述的神经生理学研究,在一篇题为《正则集代数》的论文中定义了“正则集”,并在其上定义了一个代数系统,并且引入了一种记号系统来描述正则集,这种记号系统被他称为“正则表达式”。在理论数学的圈子里被研究了几十年之后,1968年,后来发明了UNIX系统的Ken Thompson第一个把正则表达式用于计算机领域,开发了qed和grep两个实用文本处理工具,取得了巨大成功。在此后十几年里,一大批一流计算机科学家和黑客对正则表达式进行了密集的研究和实践。在1980年代早期,UNIX运动的两个中心贝尔实验室和加州大学伯克利分校分别围绕grep工具对正则表达式引擎进行了研究和实现。与之同时,编译器“龙书”的作者Alfred Aho开发了Egrep工具,大大扩展和增强了正则表达式的功能。此后,他又与《C程序设计语言》的作者Brian Kernighan等三人一起发明了流行的awk文本编辑语言。到了1986年,正则表达式迎来了一次飞跃。先是C语言顶级黑客Henry Spencer以源代码形式发布了一个用C语言写成的正则表达式程序库(当时还不叫open source),从而把正则表达式的奥妙带入寻常百姓家,然后是技术怪杰Larry Wall横空出世,发布了Perl语言的第一个版本。自那以后,Perl一直是正则表达式的旗手,可以说,今天正则表达式的标准和地位是由Perl塑造的。Perl 5.x发布以后,正则表达式进入了稳定成熟期,其强大能力已经征服了几乎所有主流语言平台,成为每个专业开发者都必须掌握的基本工具。



2.DFA和NFA

引用
理解DFA和NFA
正则表达式引擎分成两类,一类称为DFA(确定性有穷自动机),另一类称为NFA(非确定性有穷自动机)。两类引擎要顺利工作,都必须有一个正则式和一个文本串,一个捏在手里,一个吃下去。DFA捏着文本串去比较正则式,看到一个子正则式,就把可能的匹配串全标注出来,然后再看正则式的下一个部分,根据新的匹配结果更新标注。而NFA是捏着正则式去比文本,吃掉一个字符,就把它跟正则式比较,匹配就记下来:“某年某月某日在某处匹配上了!”,然后接着往下干。一旦不匹配,就把刚吃的这个字符吐出来,一个个的吐,直到回到上一次匹配的地方。
DFA与NFA机制上的不同带来5个影响:
1. DFA对于文本串里的每一个字符只需扫描一次,比较快,但特性较少;NFA要翻来覆去吃字符、吐字符,速度慢,但是特性丰富,所以反而应用广泛,当今主要的正则表达式引擎,如Perl、Ruby、Python的re模块、Java和.NET的regex库,都是NFA的。
2. 只有NFA才支持lazy和backreference等特性;
3. NFA急于邀功请赏,所以最左子正则式优先匹配成功,因此偶尔会错过最佳匹配结果;DFA则是“最长的左子正则式优先匹配成功”。
4. NFA缺省采用greedy量词(见item 4);
5. NFA可能会陷入递归调用的陷阱而表现得性能极差。

我这里举一个例子来说明第3个影响。

例如用正则式/perl|perlman/来匹配文本 ‘perlman book’。如果是NFA,则以正则式为导向,手里捏着正则式,眼睛看着文本,一个字符一个字符的吃,吃完 ‘perl’ 以后,跟第一个子正则式/perl/已经匹配上了,于是记录在案,往下再看,吃进一个 ‘m’,这下糟了,跟子式/perl/不匹配了,于是把m吐出来,向上汇报说成功匹配 ‘perl’,不再关心其他,也不尝试后面那个子正则式/perlman/,自然也就看不到那个更好的答案了。

如果是DFA,它是以文本为导向,手里捏着文本,眼睛看着正则式,一口一口的吃。吃到/p/,就在手里的 ‘p’ 上打一个钩,记上一笔,说这个字符已经匹配上了,然后往下吃。当看到 /perl/ 之后,DFA不会停,会尝试再吃一口。这时候,第一个子正则式已经山穷水尽了,没得吃了,于是就甩掉它,去吃第二个子正则式的/m/。这一吃好了,因为又匹配上了,于是接着往下吃。直到把正则式吃完,心满意足往上报告说成功匹配了 ‘perlman’。

由此可知,要让NFA正确工作,应该使用 /perlman|perl/ 模式。

通过以上例子,可以理解为什么NFA是最左子式匹配,而DFA是最长左子式匹配。实际上,如果仔细分析,关于NFA和DFA的不同之处,都可以找出道理。而明白这些道理,对于有效应用正则表达式是非常有意义的。

写道
正则表达式的形式定义故意非常精简,避免定义多余的量词 ? 和 +,它们可以被表达为: a+ = aa* 和 a? = (a|ε)。有时增加补算子 ~ ;~R 指示在 Σ* 上的不在 R 中的所有字符串的集合。补算子是多余的,因为它使用其他算子来表达(尽管计算这种表示的过程是复杂的,而结果可能指数性的增大)。
这种意义上的正则表达式可以表达正则语言,精确的是可被有限状态自动机接受的语言类。但是在简洁性上有重要区别。某类正则语言只能用大小指数增长的自动机来描述,而要求的正则表达式的长度只线性的增长。正则表达式对应于乔姆斯基层级的类型-3文法。在另一方面,在正则表达式和不导致这种大小上的爆炸的非确定有限状态自动机(NFA)之间有简单的映射;为此 NFA 经常被用作正则表达式的替代表示。
我们还要在这种形式化中研究表达力。如下面例子所展示的,不同的正则表达式可以表达同样的语言: 这种形式化中存在着冗余。
有可能对两个给定正则表达式写一个算法来判定它们所描述的语言是否本质上相等,简约每个表达式到极小确定有限自动机,确定它们是否同构(等价)。
这种冗余可以消减到什么程度? 我们可以找到仍有完全表达力的正则表达式的有趣的子集吗? Kleene 星号和并集明显是需要的,但是我们或许可以限制它们的使用。这提出了一个令人惊奇的困难问题。因为正则表达式如此简单,没有办法在语法上把它重写成某种规范形式。过去公理化的缺乏导致了星号高度问题。最近 Dexter Kozen 用克莱尼代数公理化了正则表达式。
很多现实世界的“正则表达式”引擎实现了不能用正则表达式代数表达的特征。

目前正则引擎支持的语言种类:

引擎类型程序
DFAawk(大多数版本)、egrep(大多数版本)、flex、lex、MySQL、Procmail
传统型 NFAGNU Emacs、Java、grep(大多数版本)、less、more、.NET语言、PCRE library、Perl、PHP(所有三套正则库)、Python、Ruby、set(大多数版本)、vi
POSIX NFAmawk、Mortice Lern System's utilities、GUN Emacs(明确指定时使用)
DFA/NFA混合GNU awk、 GNU grep/egrep、 Tcl
引申阅读:
为什么输入这种正则会导致假死?http://rdc.taobao.com/team/jm/archives/2432

相关文章:

adc采样的值跳动_嵌入式er必知:模数采样知多少(最全总结)

[导读] 生活环境周围信号万万千,对于一个嵌入式er。我们利用技术去了解世界、改变世界。而一个产品要与外界物理环境打交道,一个至关重要的触角就是采样真实模拟世界的信号,翻译成芯片可理解的数字信号,进而实现很多为人服务的应…

Swift泛型

泛型是为Swift编程灵活性的一种语法&#xff0c;在函数、枚举、结构体、类中都得到充分的应用&#xff0c;它的引入可以起到占位符的作用&#xff0c;当类型暂时不确定的&#xff0c;只有等到调用函数时才能确定具体类型的时候可以引入泛型。 泛型函数 定义 fun 函数名<T,S&…

02、在层级未知情况下通过递归查找子物体

1、在在层级未知情况下通过递归查找子物体 &#xff0c;这个主要是用于UI的的层级查找中 2、代码&#xff1a; 1 using System.Collections;2 using System.Collections.Generic;3 using UnityEngine;4 5 public class EnemyManager : MonoBehaviour6 {7 8 private GameOb…

CentOS装机必备-基本设置以及缺失文件

SecureCRT中注意不要使用以Ascii方式上传文件&#xff0c;只有在需要的地方才使用。主要是虚拟机中安装CentOS每次总会做一些设置&#xff0c;记录下来方便以后。 纯粹基本设置&#xff0c;比如本地SecureCRT可以连接虚拟机中的CentOS。 复杂的非基本设置见&#xff1a;Linux …

unity替换mesh测试

直接替换SkinnedMeshRender的Mesh&#xff0c;实现所谓断肢效果(不过最近发现&#xff0c;绑定多mesh似乎更好实现这样的效果。有时间准备写一篇)&#xff1a; 只要不改变两个Mesh原始文件的层级&#xff0c;就不会出现权重的错乱问题。 权重映射的测试&#xff1a;http://www.…

matlab中patch命令_matlab 放大平移图形是超出边界问题的处理

matlab提供的图形放大和平移函数zoom和pan可以通过鼠标来控制图形&#xff0c;非常方便&#xff0c;在工具条toolbar上也有对应的按钮。但是在放大或平移自己画的数据图是&#xff0c;有时会出现部分图形超出了坐标系的边界的问题&#xff0c;非常奇怪。经分析和试验&#xff0…

关于虚拟化技术软硬件兼容问题的探讨

VMware十几年前就已经出现&#xff0c;个人最早使用VMware的时间似乎是2001年或者2002年&#xff0c;当时可以在个人电脑上通过VMware虚拟多套系统&#xff0c;用于学习研究&#xff08;做实验往往会破坏系统&#xff0c;当时VMware在一些场景下还是比较流行的&#xff09;。由…

自己开发操作系统

算是《30天自制操作系统》的读书笔记吧&#xff0c;但是我觉得原书不少地方啰嗦&#xff0c;某些做法值得商榷 http://product.china-pub.com/36828381.二进制编译器 首先下载Bzl1621.lzh&#xff0c;这个可以把二进制数编辑的软件。 BZ启动画面打开img文件2.使用虚拟机加载IMG…

广东科技学院专插本c语言考卷_广东科技学院第二届红色文化节之红色影视经典配音大赛决赛...

红色经典影视配音大赛追忆革命岁月&#xff0c;传承红色文化&#xff0c;激扬青春生命&#xff0c;传承红色精神&#xff0c;为了让广大师生感受到红色影视经典的魅力和配音的乐趣&#xff0c;加深对红色文化的理解&#xff0c;提高师生们的爱国情怀。2020年12月16日19&#xf…

Social regularizations

trust-aware &#xff1a;如何从隐式信任中导出显示信任。链接预测就是搞这一方面的么&#xff1f; 和类似谱聚类的拉普拉斯矩阵结合在一起&#xff0c;没怎么看。

阿里P7架构师的成长之路

前言 系统架构师是近几年来在国内外迅速成长并发展良好的一个职位&#xff0c;它的重要性及给互联网行业所带来的影响是不言而喻的。很多程序员把成为一名优秀的架构师作为自己职业生涯奋斗的目标&#xff0c;但很多人努力却用不对地方&#xff0c;前段时间我与在阿里的P7架构师…

cad的文字嵌入线条_带你玩转CAD!

CAD画图已经成为化工人的必备技能。什么&#xff0c;这么多CAD必备技巧你居然还不知道&#xff1f;我该拿什么拯救你&#xff0c;我最最最最最最亲爱的旁友&#xff01;&#xff01;&#xff01;下面给大家整理了50个相见恨晚的CAD技巧&#xff0c;带你玩转CAD&#xff01;&…

BZOJ1315 : Ural1557Network Attack

找到一棵dfs搜索树&#xff0c;给每条非树边一个随机非0权值&#xff0c;每条树边为所有经过它的树边的权值的异或。 那么有2种情况是合法的&#xff1a; 1.一条边权值为0&#xff0c;一条边权值非0。 2.两条边异或和为0。 排序后统计即可&#xff0c;时间复杂度$O(m\log m)$。…

android原生跳转到外网

2019独角兽企业重金招聘Python工程师标准>>> super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent new Intent(); intent.setAction("android.intent.action.VIEW"); Uri uri Uri.parse("…

linux上使用strace查看C语言级别的php源码【一种方法】

如果你希望看到C语言级别的php代码就需要使用strace 这个默认是安装了的&#xff0c;如果没有安装可以 #yum install strace查看httpd进程 #ps auxw | grep httpd有多个&#xff0c;必须停止apache [rootlocalhost usr]# /usr/local/webserver/apache2/bin/apachectl stop启动…

iphone8p百度云认证_探秘百度数据工厂Pingo的多存储后端数据联合查询技术

作者介绍&#xff1a;张志宏&#xff0c;2013年加入百度大数据部&#xff0c;曾作为核心成员参与百度大数据平台的搭建。目前是百度数据工厂Pingo核心团队的技术负责人。Pingo是来自百度的离线大数据集成开发平台&#xff0c;使用Spark作为计算引擎&#xff0c;深度整合了资源调…

JavaScript文件中调用AngularJS内部方法或改变$scope变量

需要在其他JavaScript文件中调用AngularJS内部方法或改变$scope变量&#xff0c;同时还要保持双向数据绑定&#xff1b; 首先获取AngularJS application&#xff1a; 方法一&#xff1a;通过controller来获取app var appElement document.querySelector([ng-controllermainCon…

web类协议脚本-飞机订票系统示例

以下是LR自带的飞机订票系统的Demo&#xff0c;希望能帮助大家。 Action() {int iRand;int iTmp;char *strTmpA;char *strTmpB;char *strTmpC;char *position;if ((strTmpA (char *)malloc(100 * sizeof(char))) NULL) { lr_output_message ("Insufficient memory avail…

ACCEPT()和ACCEPT4()

ACCEPT章节&#xff1a;Linux 程序员手册 (2) 更新&#xff1a;2010-09-10到 易美翻译 翻译名字accept - 通过套接口接受一个连接 概要 #include Esys/types.h> /* 参看 “注意小节” */ #include Esys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen…

没有提示_华为手机发出莫名的提示音,打开什么也没有?原来是它们在作怪

不知道你们有没有遇到过这样的情况&#xff0c;在使用手机的过程中会出现一个非常奇怪的现象&#xff1a;当你听到手机发出声音&#xff0c;打开手机却发现什么通知也没有&#xff1f;这一度让我感到很困扰&#xff0c;本着“打破砂锅问到底”的精神&#xff0c;终于让我找到了…

近段时间佛我就偶尔无

jo建瓯市金佛玩手机欧力紧凑度 我株型紧凑我阿九倨傲四局李嘉诚转载于:https://juejin.im/post/5b8e5263e51d4538e2278c9b

php内核探索方法与资源

PHP内核探索 TIPI深入理解PHP内核 风雪之隅PHP源码分析 《php扩展开发及内核应用》 百度XLQ Gods blog codinglabsPHP内核探索&#xff1a;从SAPI接口开始PHP内核探索&#xff1a;一次请求的开始与结束PHP内核探索&#xff1a;一次请求生命周期PHP内核探索&#xff1a;单进程SA…

feign调用走不走网关全局拦截_feign服务端出异常客户端处理的方法

在使用feign进行远程方法调用时&#xff0c;如果远程服务端方法出现异常&#xff0c;客户端有时需要捕获&#xff0c;并且把异常信息返回给前端&#xff0c;而如果在开启熔断之后&#xff0c;这个异常会被消化&#xff0c;所以说&#xff0c;如果希望拿到服务端异常&#xff0c…

配置Cesium编译环境

1、安装node.js https://nodejs.org/en/ 2、配置node.js 在node.js安装目录下新建node_global、node_cache两个文件夹&#xff0c;并把node_global添加到环境变量 eg.D:\app\nodejs npm config set prefix D:\app\nodejs\node_global npm config set cache D:\app\nodejs\node_…

迷你世界电锯机器人_迷你世界:三分钟制作超简单飞翔石像机器人报道!

更多游戏资讯&#xff0c;请点击上方蓝字查询&#xff01;哈喽&#xff0c;大家好&#xff0c;还记得我之前分享的超简单的石像机器人吗&#xff1f;不记得了吗&#xff1f;我再帮助大家回忆回忆&#xff0c;之前研游酱分享的石像机器人总共是分两篇文章&#xff0c;一个是不会…

J2EE 第二阶段项目之编写代码(四)

我的任务就是项目统计。 1 效益统计 1 教育效益统计表 &#xff08;教育效益统计表&#xff0c;增,改&#xff0c;查看&#xff0c;查&#xff09; 2 农牧林效益统计表 &#xff08;农牧林效益统计表&#xff0c;增&#xff0c;改&#xff0c;查看&#xff0c;查&#xff09; 3…

PHP安装扩展mcrypt以及相关依赖项 【PHP安装PECL扩展的方法】

一&#xff1a;Mcrypt简介 Mcrypt是PHP的一个扩展&#xff0c;完成了常用加密算法的封装。其实该扩展是对mcrypt标准类库的封装&#xff0c;mcrypt完成了相当多的常用加密算法&#xff0c;如DES, TripleDES, Blowfish (default), 3-WAY, SAFER-SK64, SAFER-SK128, TWOFISH, TEA…

Javascript到PHP加密通讯的简单实现

互联网上大多数网站&#xff0c;用户的数据都是以明文形式直接提交到后端CGI&#xff0c;服务器之间的访问也大都是明文传输&#xff0c;这样可被一些别有用心之人通过一些手段监听到。对安全性要求较高的网站&#xff0c;比如银行和大型企业等都会使用HTTPS对通讯过程进行加密…

MYSQL添加新用户 MYSQL为用户创建数据库 MYSQL为新用户分配权限

2019独角兽企业重金招聘Python工程师标准>>> 1.新建用户 //登录MYSQL >mysql -u root -p >密码 //创建用户 mysql> insert into mysql.user&#xff08;Host,User,Password&#xff09; values&#xff08;‘localhost’&#xff0c;jeecn’&#xff0c;pa…

uml具有多种视图_UML建模与架构文档化

UML(统一建模语言) 是用元模型描述的&#xff0c;元模型是4层元模型体系结构模式中的一层。此模式的其他层次分别是元-元模型层、模型层和用户对象层。在原模型层&#xff0c;UML元模型 又被分解为三个子逻辑包&#xff1a;基础包(核心、扩展机制和数据模型)、行为元素包(描述模…