正则表达式模版ppt课件.ppt
《正则表达式模版ppt课件.ppt》由会员分享,可在线阅读,更多相关《正则表达式模版ppt课件.ppt(85页珍藏版)》请在三一办公上搜索。
1、正则表达式,-张进平,主要内容,正则表达式基本语法正则表达式的特性和流派概述正则表达式的匹配原理正则表达式的使用技巧和性能改善具体语言(java)中的正则表达式附录-JavaScript的RegExp对象参考资料,一.正则表达式的基本语法,模式(Pattern)文件名模式(filename Pattern)在文件系统中提供了某些特殊的字符,作为通配符如:*.txt 等。能找到所有扩展名为txt的文件。在很多系统中都自己系统描述的特定字符,表示特殊的 意义,但是这种描述相当有限-只涉及到文件名。,通用模式语言(generalized Pattern language)要处理我们所想到得任何文本,
2、如:报表,散文,诗歌,表格,html,程序代码,单词表等,简单的文件模式显得无能为力。一种新的,功能强大的不同语言以各种方式来实现和使用的模式语言来弥补它的不足。这种通用模式语言和本身被称为“正则表达式(regular expression)”,2.正则表达式的测试 正则表达式本身不能完成任何工作,它的使用需要有支持正则表达式的宿主语言。以后讲解中我们用java和javascript完成。这里的测试我们用一个支持正则表达式的文本检索器(agrep)来测试。agrep的下载网站:http:/www.tgries.de/agrep/#DOWNLOAD agrep有各种版本,我这里下了win32的,
3、方便测试也不用安装。agrep命令格式:agrep“正则表达式”文件名,3.正则表达式的组成,普通文本就像英语的基本单词而元字符就是它的语法体系正则表达式和文件名模式的区别在于,正则表达式的元字符提供了更强大的描述能力。,4.正则表达式的元字符行的起始和结束 行的起始用脱字符 表示,结束用美元符$表示。行开始和结束只匹配位置,不指具体文本。如:cat 表示匹配一个行起始,一个字符c,一个字符a一个 字符t,意思是匹配以cat开始的行。cat$表示匹配一个行起始,一个字符c,一个字符a一个 字符t,一个$,意思是匹配只有cat的行。举例测试,4.正则表达式的元字符字符组 匹配这里列出来的任何字符
4、。如:你要检索html标签h1到h6,你可以这么写 h 123456 手机号码前两位可以这么写:1358 再如:你不确定grey怎么拼,不知道grey 还是gray对 你可以这么检索如:greay举例测试,4.正则表达式的元字符连字符-表示一个范围,在字符组内部的元字符,叫字符组元字符。如:上面的html标签h123456,我们现在可以写成h1-6,它先匹配一个h,然后再匹配1到6中任意一个字符。再如:a-z举例测试注意:连字符在字符组的开头不是元字符,只有在中间表示范围的时候才是元字符。其他元字符在字符组内也不是元字符。,4.正则表达式的元字符排除型字符组 它的意思是匹配除了这里列出的任何字
5、符。这里的 和行开始是一样的字符。但是意义截然不同。如:1-6 意思是除了1到6之外任何字符。c 表示不是字符c开始的行。举例测试,4.正则表达式的元字符多选结构或|它的意思就是 或(or)它能任意的子表达式,能把多个字表达式合并。我们回头看我们的例子greay,在这里我们可以这么 写:grey|gray 也可写成:gr(a|e)y 这里括号也是元字符,它表示我们划定多选结构的范围。举例测试,4.正则表达式的元字符问题:基于原来上面的问题,请gr(a|e)y,gra|ey,graey 的区别?gra|ey表示的不是我们所需要的东西,因为|在字符组 内不是元字符,它表示的是grey,gr|y,g
6、ray中的一 个。gr(a|e)y和graey都能达到我们的目的,但如果你觉得 gr(a|e)y没什么大的用处,那么你错了!他们的本 质区别在于一个是多选结构,一个是字符组,字符 组只能匹配单个字符,多选结构匹配的是完整的分 支结构。举例测试,4.正则表达式的元字符单词分界符 匹配单词开始,单词结束 如:表示单词开始,然后匹配单词cat,然后匹配单词结束。有些版本不支持,我用的这个就不支持,而且在java,.net,Perl语言中都是b来表示的,所以我们这里只有用java的b来测试。举例测试java测试PatternTset6.java,4.正则表达式的元字符可选项?放在一个字符后面表示可选字
7、符,它的出现并非匹配成功的必要条件。在英语中color和 colour表示的同一个意思,我们检索的时候两个都检索,如下表示。如:colou?r 注:agrep不支持“?”符号举例测试java测试 PatternTset.java,4.正则表达式的元字符其他量词*和+和?一样,*,+他们称作量词,表示出现的次数。+表示一次或多次,那么就有了至少一次的限制。*表示任意多次或者不出现。因为可以不出现,所以*和?不会影响整个正则表达式的匹配是否成功。他们只会影响匹配的最终结果,也就是匹配成功的字符串。如正整数我们可以这么写:1-90-9*举例测试java测试 PatternTset.java,4.正则
8、表达式的元字符区间量词 min,max 表示重复出现的次数。对上面的正整数做限制条件4位以内的正整数我们可以这么写:1-90-90,3举例测试java测试PatternTest5.java,4.正则表达式的元字符括号及反向引用 在很多软件和文本工具中,括号能捕获匹配过的字符,再用1,2这样的字符序列来记住他们。javaScript测试:var ret=/(d)1$/;var b=ret.test(“22”);alert(b);有些版本的grep是不支持的,我用的这个就不支持。有些语言也不支持,但是它支持捕获组和非捕获组的 概念,原理一样,具体看下节。举例测试 java测试BackRefence
9、.java,4.正则表达式的元字符捕获组和非捕获组 捕获型括号()在用括号的时候它会自动记住从左到右从第一个开 括号匹配成功的字符作为第一组,放在一个所谓捕获组的变量里,第二个放在第二个变量里,以此类推。Perl5语言它放在$1,$2,$3中,java语言它也可以放在$1中,也可放在一个叫groups 的数组变量里。每次取的时候就可以直接getgroup(index)来取到。举例测试 java测试BackRefence.java,4.正则表达式的元字符捕获组和非捕获组 非捕获型括号(?:)括号内的开始加了问号和冒号。大多数情况下我们并不想捕获匹配数据,这样对我们系统的效率和性能消耗很大。那么我
10、们就可以用非捕获型括号,提高我们的效率。关于正则表达式的效率问题在后面章节里讲解 如:(fffff|dddd)|eeeee)举例测试 java测试BackRefence.java,4.正则表达式的元字符捕获组和非捕获组 如:有这么个需求,允许客户端数据手机号码或电话号码,还可以是邮箱,我们根据正则表达式可以获得具体是什么,再根据我们捕获到的数据进行后续处 理,如打电话,或发邮件。,举例测试 java测试 groupTset.java,4.正则表达式的元字符转义字符 也许你已经发现,正则表达式里有很多元字符,如果想 检索元字符,那么怎么办,转义字符就是解决这个问题的,如果你想查找.这个元字符,那
11、么你应该写成.这种形式。如:检索 那么我们应该写成:举例测试,4.正则表达式的元字符其他软件程序中的元字符 d 相当于0-9 D 相当于0-9 w 相当于0-9a-zA-Z_ 这里包括下划线 W 相当于0-9a-zA-Z_ s 包括空格符,回车符,制表符,进纸符等 S 除了所有空白符s外的所有字符 r 回车符制表符t 制表符 n 换行符举例测试 java测试PatternTest3.java,4.正则表达式的元字符环视(lookaround)它不匹配任何字符,只匹配文本中的特定位置,这一点和单词边界符b,起始符,结束符$很相似。环视分为四种,如下:,4.正则表达式的元字符肯定型顺序环视 如正则
12、表达式Jeffrey匹配 by Jeffrey friedl时可以成功匹配Jeffrey 而正则表达式(?=Jeffrey)匹配的是如下位置:这样看着好像没什么意思,也看不出什么作用,现在我们把我们的正则表达式改成(?=Jeffrey)Jeff,这个时候我们再去匹配这两个行:1.by Jeffrey friedl 2.by Thomas Jefferson,4.正则表达式的元字符肯定型顺序环视(java测试:PatternTset7.java)我们会惊奇的发现字符串1被分割了,而字符串2没有被分割。答案很简单,本身字符Jeff是匹配的,只是没匹配环视(?=Jeffrey),这样把范围缩小到了J
13、effrey,意思是只有Jeffrey里的Jeff才是我们真正想找的那个字符串,才能真正被匹配。请看下图:,肯定型顺序环视图,4.正则表达式的元字符逆序,否定 顺序环视明白了,逆序就很容易了,意思就是当前位置的左边要匹配环视的文本。也就是环视的结果在环视匹配文本的右面。否定更简单了,肯定就是要环视的测试文本匹配才算成功,否定就是要环视测试的文本和要测试的文本不匹配才算环视匹配成功。,5.元字符-总结,二.正则表达式的特性和流派概述,正则表达式的起源 20世纪40年代两位神经学家Warren McCulloch和Walter Pitts研究出一种模型来描述神经系统的神经元。20世纪50年代和60
14、年代理论数学界对正则表达式进行了充分研究。1968年Ken Thompson发表了Regular Expression Search Algorihm描述了正则表达式编译器。该编译器后来成了IBM的Object代码,由此诞生了qed,这种编译器后来成了Unix中的ed编辑器的基础。,ed的正则表达式随然没qed的先进,但是得到了大规模应用,有条命令叫“g/Regular Expression/p”,读作“Global Regular Expression Print(应用正则表达式全局输出)”,这个实用的功能最终独立成了grep,之后又产生了egrep,agrep-都是grep的扩展。grep
15、经过漫长的发展形成egrep的同时,其他程序awk,lex,sed也在发展,并添加了新的功能,众多程序员的修改,结果就形成了巨大的迷局。1986年POSI(Portable Operating SysTem Interface)(可移植操作系统接口)为了理清正则表达式的混乱局面,把长见的正则表达式分为两类Basic Regular Expressions(BREs)和Extended Regular Expressions(EREs).,POSI正则表达式流派概览,2.各种语言之间的差异在于以下三点:支持的元字符,以及这些元字符的意义。也就是我们说的流派(flavor)。正则表达式与语言或工具
16、的“交互“(inteface)方式。譬如如何进行正则表达式的操作,容许进行哪些操作,以及这些操作的目标文本类型。正则表达式引擎如何将表达式应用到文本中。语言或工具的设计者实现正则表达式方法,对正则表达式能够取得到的结果又重要的影响。,若干工具正则表达式流派的简要参考,程序设计语言3种处理正则表达式的方式:集成式(integrated)程序式(procedural)面向对象式(object-oriented)第一种方式中,正则表达式是直接内建在语言中的,Perl就是如此,在其他两种方式中,正则表达式不属于语言的低级语法。相反,普通的函数接受普通的字符,把他们当做正则表达式进行处理。由不同的的函数
17、进行不同的、关系到一个或多个正则表达式的操作。大多数语言(不包括Perl)PHP,Java,.net,Python,Ruby等采用的是这两种方式之一。,Perl(一种脚本语言)例子:$/=“.n”;while()next if!s/b(a-z+)(?:s|+)+)(1b)/e7m$1em$2e7m$3em/ig;s/(?:e*n)+/mg;s/$ARGV:/mg;Print;这里并不奢望能看懂上面代码,何况我们不懂Perl,就算懂Perl的人也未必一下看的明白,只想用这个例子说明不同语言对正则表达式的交互方式程度的不同。在这里给我们的感觉就是正则表达式和程序代镶嵌很紧,所谓正则表达式和代码搭配
18、天衣无缝,正因为正则表达式找到了Perl这块肥土,才让正则表达式在Perl里显得相当出色。,java例子:public static void main(String args)Pattern p=Ppile(b n+#把捕获到得地址保存到$1.n+(n+w-.w*n+n+-w+(.-w+)*.(com|edu|info)n+)n+b n,Pattern.CASE_INSENSITIVE|Pattern.COMMENTS);Matcher m=p.matcher(text);text=m.replaceAll($1);System.out.println(text);,java例子:看如上代码
19、,你发现,元字符w写成了w,这是因为java把所有正则表达式都做字符串输入,在程序代码里他不认识w是什么,这么写也会报错误。注意:这里的换行”n”,是java里的转义字符,不属于正则表达式的内容。这里加换行的目有两个:一让我的代码看的更清楚,二是正则表达式#开始的为注释行,不换行的话都属于注释部分了。测试(EmailChange.java)分析代码作用。通过Perl和java代码的对比,我们看到语言之间正则表达式运用的差异,也看出集成式和程序式及面向对象式之间的差别。,2.正则表达式匹配模式:不区分大小写的匹配模式。(忽略大小写)宽松排列和注释模式。(忽略制表符空格等)点号通配模式(单行模式)
20、。(点号可以匹配换行等)增强的行锚点模式(多行模式)。(行锚点符能匹配任何行终止符)文字文本模式。(不认识任何元字符,全部当简单字符串处理,不当做正则表达处理),3.常见元字符和特性(略)第一节讲了最常用的元字符,其实还有很多元字符的定义规则特性及其用法,如Unicode字符集,POSIX字符集,模式修饰符等。有兴趣的同学可以去看下资料:Mastering Regular Expressiongs,3rd Edition 美Jeffref E.F.Friedl 精通正则表达式第三版 余晟 译,4.总结发展起源软件工具和语言支持情况各种程序设计支持的差异正则编译的模式下面我们接着讲 第三节 正则
21、表达式的匹配原理,三.正则表达式的匹配原理,1.引擎,不符合排放标准,符合排放标准,符合排放标准,1.引擎 最初正则引擎和汽车引擎一样,分为两种,DFA(相当于电动机)和NAF(相当于汽油机)。后来,NFA和DFA都发展了20多年了,产生了一些变体,POSIX标准出台后(相当于出了排放标准),DFA是符合POSIX的,而NFA是不符合的,所以出现了修改后符合POSIX的 NFA。这样一来正则引擎和汽车引擎的例子很相似,大概分为三种:DFA(符合POSIX标准)-电动机传统NFA(不符合POSIX)-汽油机POSIX NFA(符合POSIX)-符合排放的汽油机,1.引擎部分程序及其使用的正则引擎
22、,1.引擎 测试引擎类型 传统型NFA是广泛使用的,且很好区分,如果支持忽略优先量词。那么它就是传统型NFA(Java是支持忽略优先量词的,Java API明确说明是传统的NFA正则引擎,可查看API)。是DFA还是POSIX NFA DFA不支持捕获型括号和回溯,这一点可以明确判断DFA还是POSIX NFA,不过有双引擎的就列外了。,2.匹配基础 匹配的两条规则:优先选择最左端(最开头)的匹配结果。标准匹配量词(*,+,?,m,n)是匹配优先(greedy)的。这里给大家补充下三种量词概念(原因是在前面省略了一小段内容)测试:PatternTest5.java三种量词:1.匹配优先量词(g
23、reedy)(*,+,?,m,n)2.忽略优先量词(Reluctant)(*?,+?,?,m,n?)3.占有优先量词(Possessive)(*+,+,?+,m,n+)这两条规则是所有匹配的基础。下面我们分别来阐述。,2.匹配基础优先选择最左端(最开头)的匹配结果。这条规则很好理解,,看下面的例子:用oa匹配float。这里它会一个一个字符去找,所以我们在匹配应该说先匹配一个f,发现匹配失败,继续向前,匹配一个l,再次失败,再向前移动,匹配o成功,同时它会记住匹配成功的o,把自身向前移一位,匹配a,匹配成功并记住a,引擎停止,宣告全局匹配成功。用cat去匹配The dragging belly
24、 indicates that you cat is too fat.。这个匹配和上面一样,他最先匹配indicates里的cat,而不是you后面的cat。,2.匹配基础标准匹配量词(*,+,?,m,n)是匹配优先的。现在看看这条规则怎么理解。标准匹配优先就是匹配尽可能多的字符,一直到匹配上限位置。如:d*匹配dddddd,他会匹配所有的d。过程是这样的,先匹配一个d,匹配成功,那么把匹配成功的先保存起来,然后再尝试下一个d,如果失败,那么匹配结束,返回一已经保存的那个d,如果匹配成功,它再把第二个d保存起来,再尝试匹配下一个如此下去,直到所有尝试结束,返回保存的那些字符。它会尝试匹配尽可能
25、多的字符。,2.匹配基础过度匹配优先。大家看看.*(0-90-9)匹配 about 24 characters long应该如何匹配。按照基本量词匹配优先原则,.*会匹配所有字符,而导致(0-90-9)匹配不到,导致整个正则表达式匹配失败?其实不是这样的,当然基本量词匹配优先这条原则不会变,就是说.*还是会吃掉整个字符串,但是当(0-90-9)匹配不到的时候,它会说哥们儿你吃多了,我没的吃了,我饿死了你也会死,于是.*为了它自己不死,就吐给(0-90-9)一个字符g,(0-90-9)吃了g,发现自己匹配不了,又说哥们儿别那么小气,于是.*再吐给一个n,还是匹配不了,又要,.*再吐,知道吐了2的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 正则 表达式 模版 ppt 课件
链接地址:https://www.31ppt.com/p-3910641.html