为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

《易语言“正则表达式”详细教程》

2022-03-16 30页 doc 708KB 4阅读

用户头像 个人认证

中式烹调师

暂无简介

举报
《易语言“正则表达式”详细教程》PAGEPAGE1《易语言“正则表达式”教程》本文改编自多个文档,因此如有雷同,不是巧合。“正则表达式”的应用范围越来越广,有了这个强大的工具,我们可以做很多事情,如搜索一句话中某个特定的数据,屏蔽掉一些非法贴子的发言,网页中匹配特定数据,代码编辑框中字符的高亮等等,这都可以用正则表达式来完成。本书分为四个部分。第一部分介绍了易语言的正则表达式支持库,在这里,大家可以了解第一个正则表达式的易语言程序写法,以及一个通用的小工具的制作。第二部分介绍了正则表达式的基本语法,大家可以用上述的小工具进行试验。第三部分介绍了用...
《易语言“正则表达式”详细教程》
PAGEPAGE1《易语言“正则表达式”教程》本文改编自多个文档,因此如有雷同,不是巧合。“正则表达式”的应用范围越来越广,有了这个强大的工具,我们可以做很多事情,如搜索一句话中某个特定的数据,屏蔽掉一些非法贴子的发言,网页中匹配特定数据,代码编辑框中字符的高亮等等,这都可以用正则表达式来完成。本书分为四个部分。第一部分介绍了易语言的正则表达式支持库,在这里,大家可以了解第一个正则表达式的易语言程序写法,以及一个通用的小工具的制作。第二部分介绍了正则表达式的基本语法,大家可以用上述的小工具进行试验。第三部分介绍了用易语言写的正则表达式工具的使用方法。这些工具是由易语言用户提供的,有的工具还带有易语言源码。他们是:monkeycz、零点飞越、寻梦。第四部分介绍了正则表达式的高级技巧。目录TOC\o"1-3"\h\zHYPERLINK\l"_Toc156791784"《易语言“正则表达式”教程》PAGEREF_Toc156791784\h1HYPERLINK\l"_Toc156791785"目录PAGEREF_Toc156791785\h1HYPERLINK\l"_Toc156791786"第一章易语言正则表达式入门PAGEREF_Toc156791786\h3HYPERLINK\l"_Toc156791787"一.与DOS下的通配符类似PAGEREF_Toc156791787\h3HYPERLINK\l"_Toc156791788"二.初步了解正则表达式的规定PAGEREF_Toc156791788\h3HYPERLINK\l"_Toc156791789"三.一个速查列表PAGEREF_Toc156791789\h4HYPERLINK\l"_Toc156791790"四.正则表达式支持库的命令PAGEREF_Toc156791790\h5HYPERLINK\l"_Toc156791791"4.1第1个正则表达式程序PAGEREF_Toc156791791\h5HYPERLINK\l"_Toc156791792"4.2第2个正则表达式例程PAGEREF_Toc156791792\h7HYPERLINK\l"_Toc156791793"4.3第3个例程PAGEREF_Toc156791793\h8HYPERLINK\l"_Toc156791794"4.4一个小型的正则工具PAGEREF_Toc156791794\h9HYPERLINK\l"_Toc156791795"第二章揭开正则表达式的神秘面纱PAGEREF_Toc156791795\h11HYPERLINK\l"_Toc156791796"引言PAGEREF_Toc156791796\h12HYPERLINK\l"_Toc156791797"一.正则表达式规则PAGEREF_Toc156791797\h12HYPERLINK\l"_Toc156791798"1.1普通字符PAGEREF_Toc156791798\h12HYPERLINK\l"_Toc156791799"1.2简单的转义字符PAGEREF_Toc156791799\h13HYPERLINK\l"_Toc156791800"1.3能够与“多种字符”匹配的表达式PAGEREF_Toc156791800\h14HYPERLINK\l"_Toc156791801"1.4自定义能够匹配“多种字符”的表达式PAGEREF_Toc156791801\h16HYPERLINK\l"_Toc156791802"1.5修饰匹配次数的特殊符号PAGEREF_Toc156791802\h17HYPERLINK\l"_Toc156791803"1.6其他一些代表抽象意义的特殊符号PAGEREF_Toc156791803\h20HYPERLINK\l"_Toc156791804"二.正则表达式中的一些高级规则PAGEREF_Toc156791804\h21HYPERLINK\l"_Toc156791805"2.1匹配次数中的贪婪与非贪婪PAGEREF_Toc156791805\h21HYPERLINK\l"_Toc156791806"2.2反向引用\1,\2...PAGEREF_Toc156791806\h23HYPERLINK\l"_Toc156791807"2.3预搜索,不匹配;反向预搜索,不匹配PAGEREF_Toc156791807\h24HYPERLINK\l"_Toc156791808"三.其他通用规则PAGEREF_Toc156791808\h25HYPERLINK\l"_Toc156791809"四.其他提示PAGEREF_Toc156791809\h27HYPERLINK\l"_Toc156791810"第三章正则表达式工具与实例PAGEREF_Toc156791810\h28HYPERLINK\l"_Toc156791811"一.正则表达式支持库PAGEREF_Toc156791811\h29HYPERLINK\l"_Toc156791812"1.1“正则表达式”数据类型PAGEREF_Toc156791812\h29HYPERLINK\l"_Toc156791813"1.2“搜索结果”数据类型PAGEREF_Toc156791813\h30HYPERLINK\l"_Toc156791814"二.正则表达式实用工具PAGEREF_Toc156791814\h30HYPERLINK\l"_Toc156791815"2.1一个成品工具PAGEREF_Toc156791815\h30HYPERLINK\l"_Toc156791816"2.2易语言写的工具PAGEREF_Toc156791816\h33HYPERLINK\l"_Toc156791817"三.应用实例PAGEREF_Toc156791817\h34HYPERLINK\l"_Toc156791818"3.1实例1PAGEREF_Toc156791818\h34HYPERLINK\l"_Toc156791819"3.2实例2PAGEREF_Toc156791819\h36HYPERLINK\l"_Toc156791820"3.3实例3PAGEREF_Toc156791820\h37HYPERLINK\l"_Toc156791821"3.4实例4PAGEREF_Toc156791821\h37HYPERLINK\l"_Toc156791822"第四章正则表达式话题PAGEREF_Toc156791822\h38HYPERLINK\l"_Toc156791823"引言PAGEREF_Toc156791823\h38HYPERLINK\l"_Toc156791824"一.表达式的递归匹配PAGEREF_Toc156791824\h38HYPERLINK\l"_Toc156791825"1.1匹配未知层次的嵌套PAGEREF_Toc156791825\h38HYPERLINK\l"_Toc156791826"1.2匹配有限层次的嵌套PAGEREF_Toc156791826\h39HYPERLINK\l"_Toc156791827"二.非贪婪匹配的效率PAGEREF_Toc156791827\h40HYPERLINK\l"_Toc156791828"2.1效率陷阱的产生PAGEREF_Toc156791828\h40HYPERLINK\l"_Toc156791829"2.2效率陷阱的避免PAGEREF_Toc156791829\h41HYPERLINK\l"_Toc156791830"附录:PAGEREF_Toc156791830\h42HYPERLINK\l"_Toc156791831"一.17种常用正则表达式PAGEREF_Toc156791831\h42第一章易语言正则表达式入门一.与DOS下的通配符类似其实,所谓的“正则表达式”,是大家一直在使用的,记得吗?在搜索文件时,会使用一种威力巨大的武器——DOS通配符——“?”和“*”。这就是最常用的正则表达式。例如:123.*表示所有文件名为123的文件,如123.txt,123.doc,123.wps,123.swf,123.xls等。“中国?.doc”表示所有文件名类似于中国1.doc、中国2.doc、中国x.doc这样的文件。上述DOS下的通配符用“?”号代表一个字符,“*”号代表任意个字符,但在正则表达式中,可能这些都有些改变。如“*”号匹配的就不一样。下面看看正则表达式是如何规定的吧。二.初步了解正则表达式的规定正则表达式正是在“DOS通配符”基础上复杂化而得到的。其最常用的表达式可能是:*匹配0或多个正好在它之前的那个字符。例如a*意味着能够匹配任意数量的a字符.匹配任何单个字符。例如r.t匹配这些字符串:rat、rut、rt,但是不匹配root(等同于DOS通配符下的?号。)^匹配一行的开始。例如^When能够匹配字符串"Wheninthecourseofhumanevents"的开始,但是不能匹配"WhatandWheninthe"。$匹配行结束符。例如正则表达式weasel$能够匹配字符串"He'saweasel"的末尾,但是不能匹配字符串"Theyareabunchofweasels."。在这些字符中,可以使用\.来表示.,\*表示*,不过,这种情况出现得很少,如果不能理解,可以暂时不理它,到用的时候就明白了。正则表达式还有一个强大的符号:[],这个[]所括的内容,可以不按顺序进行匹配。如[abc]匹配abc,acb,bac,bca,cab,cba这6个文本[0-9]匹配任意0到9的数字[a-z]匹配所有小写字母[A-Z]匹配所有大写字母当然,你可以把它们混在一起写成[a-z0-9]这种样子。很多时候,我们需要检查文本中的非数字,我们就可以使用^这个符号,表示“除了……”[^0-9]匹配所有非数字文本[^a-zA-Z]匹配所有非字母的文本[^FONT]匹配所有不含FONT的文本三.一个速查列表下面用一个表来表示:*前面元素出现0次以上.匹配任何单个字符?前面元素出现0次或1次+前面元素出现1次以上^表示开头。$表示结尾。.*表示0个以上的任意字符。[]范围描述符。[a-z]表示从a到z之间的任意一个。\w英文字母和数字。即[0-9A-Za-z]。\W非英文字母和数字\s空字符,即[\t\n\r\f]。\S非空字符。\d数字,即[0-9]。\D非数字。\b词边界字符(在范围描述符外部时)\B非词边界字符\b退格符(0x08)(在范围描述符内部时){m,n}前面元素最少出现m次,最多出现n次|选择()群组其他字符该字符本身四.正则表达式支持库的命令基本的规则这些也就够了。下面将讲一讲易语言中正则表达式的数据类型和几个相关命令,相关的数据类型有两个:正则表达式和搜索结果。如下图所示:4.1第1个正则表达式程序新建一个易语言程序,界面如下图所示:按钮被单击事件代码如下:.局部变量正则表达式1,正则表达式正则表达式1.创建(“A.C”,假)编辑框2.内容=到文本(正则表达式1.匹配(编辑框1.内容))如下图所示:在这里,“正则表达式1”是一个正则对象,使用“创建”方法建议了一个“A.C”正则表达式,然后与编辑框1中的内容进行正则比较,最后得出结论。运行后,大家只要输入三个字符,前为A后为C都会返回真。如下图所示:但如果是小写或多于三个字符,那么返回就会是假。如下图所示:大家也许会问,这样匹配有意义吗?我只能说,有没有意义只在于你怎么用了,如:可用于程序加密时,不采用判断语句,也不采用循环语句,而是用正则去匹配是否注册成功,以及可以进行程序名称的检查,程序中一些文字的检查等,这可能让一些不会正则的破解者很难下手。4.2第2个正则表达式例程通过第一个正则程序,大家会了解正则匹配的重要性,也了解了易语言正则支持库的基本使用方法,下面这个例程可以让大家了解正则会返回一些更多的内容,大家如何去取回这些信息呢。下面改动上述程序中的一些代码为以下:.局部变量正则表达式1,正则表达式.局部变量搜索结果1,搜索结果,,"0"正则表达式1.创建(“A.C”,假)搜索结果1=正则表达式1.搜索全部(编辑框1.内容)编辑框2.内容=搜索结果1[1].取匹配文本(编辑框1.内容,)改动后如下所示:在这里,增加了一个搜索结果的对象,用这个对象接收正则表达式匹配的结果,然后从中提取出大家想要的数据。上述易语言代码的运行结果如下图所示:改动上面编辑框的内容后,结果如下:这次是较为重要的一环,即我们知道了取回的内容。即由A和C包含的内容。以及下面会论述到的位置信息。取回的包含的内容意义重大,如:可以取回一对括号内的内容,这也是为了查找的方便。4.3第3个例程这次的工作任务是取一批文字中的所有字母与数字内容。按钮被单击事件代码如下:.局部变量正则表达式1,正则表达式.局部变量搜索结果1,搜索结果,,"0".局部变量数组索引,整数型正则表达式1.创建(“[a-z0-9”+#换行符+“]”,假)'[]中间的内容,就是要搜索的内容,可以是任意字符,包括换行、空格、特殊符号.但注意如果有字符"^",就表示"除了",如"[^abc]"表示"除了abc",现在,我们给出的表达式意思是匹配含字母、数字、换行符的文本,后面那个"假"意思是不区分大小写,你写成真也没有问题。搜索结果1=正则表达式1.搜索全部(编辑框1.内容)'搜索结果是个数组,实际上存放的是字符串搜索后的各种参数,例如位置等,可以用"取匹配文本(,)"方法将其取出,注意它的第一个参数必须和"搜索全部()"的参数一致编辑框2.内容=“”.计次循环首(取数组成员数(搜索结果1),数组索引)编辑框2.加入文本(搜索结果1[数组索引].取匹配文本(编辑框1.内容,)).计次循环尾()图片如下所示:运行后,大家可以在上面的编辑框中输入中文与字母数字的混合,点击按钮后,就可以从中提取出字母与数字了。运行效果如下图所示:4.4一个小型的正则工具在这里,大家将学会制作一个小型的正则表达式工具,使用这个工具进行下面章节更加细致的学习。这个例程也可以在本书的随书光盘中找到。程序界面如下所示安排:按钮被单击事件的代码如下:.局部变量正则表达式1,正则表达式.局部变量搜索结果1,搜索结果,,"0".局部变量位置1,整数型正则表达式1.创建(组合框1.内容,假).如果真(正则表达式1.是否为空()=真)连续赋值(“”,编辑框A.内容,编辑框B.内容,编辑框C.内容,编辑框D.内容,编辑框2.内容)返回().如果真结束编辑框2.内容=到文本(正则表达式1.匹配(编辑框1.内容))搜索结果1=正则表达式1.搜索全部(编辑框1.内容).如果真(取数组下标(搜索结果1,)=0)连续赋值(“”,编辑框A.内容,编辑框B.内容,编辑框C.内容,编辑框D.内容,编辑框2.内容)返回().如果真结束编辑框A.内容=搜索结果1[1].取匹配文本(编辑框1.内容,位置1)编辑框B.内容=到文本(位置1)编辑框C.内容=到文本(位置1+取文本长度(编辑框A.内容))编辑框D.内容=到文本(取文本长度(编辑框A.内容))抓图如下:通过上述代码后,运行效果如下:上述是测试“匹配”方法中注释的内容:正则表达式.创建(“易语言4\.0(模块|支持库)?”)信息框(正则表达式.匹配(“易语言4.0支持库”),0,)在第二章中,大家会发现本书大量用到了这个小程序。请置这个程序的启动窗口总在最前。注意:下标从0开始还是从1开始,因当前编程语言的不同而可能不同。第二章揭开正则表达式的神秘面纱[原创文章,转载请保留或注明出处:HYPERLINK"http://www.regexlab.com/zh/regref.htm"http://www.regexlab.com/zh/regref.htm]引言正则表达式(regularexpression)描述了一种字符串匹配的模式,可以用来:(1)检查一个串中是否含有符合某个规则的子串,并且可以得到这个子串;(2)根据匹配规则对字符串进行灵活的替换操作。正则表达式学习起来其实是很简单的,不多的几个较为抽象的概念也很容易理解。之所以很多人感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难;另一方面,各种引擎自带的文档一般都要介绍它特有的功能,然而这部分特有的功能并不是大家首先要理解的。一.正则表达式规则1.1普通字符   字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是“普通字符”。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。举例1:表达式“c”,在匹配字符串“abcde”时,匹配结果是:成功;匹配到的内容是:“c”;匹配到的位置是:开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)举例2:表达式“bcd”,在匹配字符串“abcde”时,匹配结果是:成功;匹配到的内容是:“bcd”;匹配到的位置是:开始于1,结束于4。1.2简单的转义字符   一些不便书写的字符,采用在前面加"\"的方法。这些字符其实我们都已经熟知了。表达式可匹配\r,\n代表回车和换行符\t制表符\\代表"\"本身   还有其他一些在后边章节中有特殊用处的标点符号,在前面加“\”后,就代表该符号本身。比如:^,$都有特殊意义,如果要想匹配字符串中“^”和“$”字符,则表达式就需要写成“\^”和“\$”。表达式可匹配\^匹配^符号本身\$匹配$符号本身\.匹配小数点(.)本身这些转义字符的匹配方法与“普通字符”是类似的。也是匹配与之相同的一个字符。举例1:表达式“\$d”,在匹配字符串“abc$de”时,匹配结果是:成功;匹配到的内容是:“$d”;匹配到的位置是:开始于3,结束于5。1.3能够与“多种字符”匹配的表达式   正则表达式中的一些表示方法,可以匹配“多种字符”其中的任意一个字符。比如,表达式“\d”可以匹配任意一个数字。虽然可以匹配其中任意字符,但是只能是一个,不是多个。这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。表达式可匹配\d任意一个数字,0~9中的任意一个\w任意一个字母或数字或下划线,也就是A~Z,a~z,0~9,_中任意一个\s包括空格、制表符、换页符等空白字符的其中任意一个.小数点可以匹配除了换行符(\n)以外的任意一个字符举例1:表达式“\d\d”,在匹配“abc123”时,匹配的结果是:成功;匹配到的内容是:“12”;匹配到的位置是:开始于3,结束于5。举例2:表达式“a.\d”,在匹配“aaa100”时,匹配的结果是:成功;匹配到的内容是:“aa1”;匹配到的位置是:开始于1,结束于4。1.4自定义能够匹配“多种字符”的表达式   使用方括号[]包含一系列字符,能够匹配其中任意一个字符。用[^]包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。表达式可匹配[ab5@]匹配"a"或"b"或"5"或"@"[^abc]匹配"a","b","c"之外的任意一个字符[f-k]匹配"f"~"k"之间的任意一个字母[^A-F0-3]匹配"A"~"F","0"~"3"之外的任意一个字符举例1:表达式“[bcd][bcd]”匹配“abc123”时,匹配的结果是:成功;匹配到的内容是:“bc”;匹配到的位置是:开始于1,结束于3。举例2:表达式“[^abc]”匹配“abc123”时,匹配的结果是:成功;匹配到的内容是:“1”;匹配到的位置是:开始于3,结束于4。1.5修饰匹配次数的特殊符号前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。使用方法是:“次数修饰”放在“被修饰的表达式”后边。比如:“[bcd][bcd]”可以写成“[bcd]{2}”。表达式作用{n}表达式重复n次,比如:HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=\\w%7b2%7d&txt=ab+c6""\w{2}"相当于"\w\w";HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=a%7b5%7d&txt=bbaaaaaddee""a{5}"相当于"aaaaa"{m,n}表达式至少重复m次,最多重复n次,比如:HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=ba%7b1,3%7d&txt=a,baaa,baa,b,ba""ba{1,3}"可以匹配"ba"或"baa"或"baaa"{m,}表达式至少重复m次,比如:HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=\\w\\d%7b2,%7d&txt=b1,a12,_456,_4AA,M12344,12346546547446534543543""\w\d{2,}"可以匹配"a12","_456","M12344"...?匹配表达式0次或者1次,相当于{0,1},比如:HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=a%5bcd%5d%3F&txt=a,c,d,ac,ad""a[cd]?"可以匹配"a","ac","ad"+表达式至少出现1次,相当于{1,},比如:HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=a%2Bb&txt=a%2Cb%2Cab%2Caab%2Caaab""a+b"可以匹配"ab","aab","aaab"...*表达式不出现或出现任意次,相当于{0,},比如:HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=%5C%5E*b&txt=%5E%2Cb%2C%5E%5E%5Eb%2C%5E%5E%5E%5E%5E%5E%5Eb""\^*b"可以匹配"b","^^^b"...举例1:表达式“\d+\.?\d*”在匹配“Itcosts$12.5”时,匹配的结果是:成功;匹配到的内容是:“12.5”;匹配到的位置是:开始于10,结束于14。举例2:表达式“go{2,8}gle”在匹配“Adsbygoooooogle”时,匹配的结果是:成功;匹配到的内容是:“goooooogle”;匹配到的位置是:开始于7,结束于17。想取得某个网址的匹配可以如下:哈哈,越来越有意思了吧,如果在一句话中找到某个网址也是非常简单的了,如下图所示:1.6其他一些代表抽象意义的特殊符号一些符号在表达式中代表抽象的特殊意义:表达式作用^与字符串开始的地方匹配,不匹配任何字符$与字符串结束的地方匹配,不匹配任何字符\b匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。举例1:表达式"^aaa"在匹配"xxxaaaxxx"时,匹配结果是:失败。因为"^"要求与字符串开始的地方匹配,因此,只有当"aaa"位于字符串的开头的时候,"^aaa"才能匹配,比如:"aaaxxxxxx"。举例2:表达式"aaa$"在匹配"xxxaaaxxx"时,匹配结果是:失败。因为"$"要求与字符串结束的地方匹配,因此,只有当"aaa"位于字符串的结尾的时候,"aaa$"才能匹配,比如:"xxxxxxaaa"。举例3:表达式".\b."在匹配"@@@abc"时,匹配结果是:成功;匹配到的内容是:"@a";匹配到的位置是:开始于2,结束于4。进一步说明:"\b"与"^"和"$"类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,其中一边是"\w"范围,另一边是非"\w"的范围。举例4:表达式“\bend\b”在匹配“weekend,endfor,end”时,匹配结果是:成功;匹配到的内容是:“end”;匹配到的位置是:开始于15,结束于18。   一些符号可以影响表达式内部的子表达式之间的关系:表达式作用|左右两边表达式之间"或"关系,匹配左边或者右边()(1).在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰(2).取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到举例5:表达式"Tom|Jack"在匹配字符串"I'mTom,heisJack"时,匹配结果是:成功;匹配到的内容是:"Tom";匹配到的位置是:开始于4,结束于7。匹配下一个时,匹配结果是:成功;匹配到的内容是:"Jack";匹配到的位置时:开始于15,结束于19。举例6:表达式"(go\s*)+"在匹配"Let'sgogogo!"时,匹配结果是:成功;匹配到内容是:"gogogo";匹配到的位置是:开始于6,结束于14。举例7:表达式"¥(\d+\.?\d*)"在匹配"$10.9,¥20.5"时,匹配的结果是:成功;匹配到的内容是:"¥20.5";匹配到的位置是:开始于6,结束于10。单独获取括号范围匹配到的内容是:"20.5"。二.正则表达式中的一些高级规则2.1匹配次数中的贪婪与非贪婪在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}","{m,}","?","*","+",具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本"dxxxdxxxd",举例如下:表达式匹配结果(d)(\w+)“\w+”将匹配第一个“d”之后的所有字符“xxxdxxxd”(d)(\w+)(d)“\w+”将匹配第一个“d”和最后一个“d”之间的所有字符“xxxdxxx”。虽然“\w+”也能够匹配上最后一个“d”,但是为了使整个表达式匹配成功,“\w+”可以“让出”它本来能够匹配的最后一个“d”由此可见,“\w+”在匹配的时候,总是尽可能多的匹配符合它规则的字符。虽然第二个举例中,它没有匹配最后一个“d”,但那也是为了让整个表达式能够匹配成功。同理,带“*”和“{m,n}”的表达式都是尽可能地多匹配,带“?”的表达式在可匹配可不匹配的时候,也是尽可能的“要匹配”。这种匹配原则就叫作“贪婪”模式。非贪婪模式:在修饰匹配次数的特殊符号后再加上一个“?”号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的“不匹配”。这种匹配原则叫作“非贪婪”模式,也叫作“勉强”模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。举例如下,针对文本“dxxxdxxxd”举例:表达式匹配结果HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=(d)(%5Cw%2B%3F)&txt=dxxxdxxxd"(d)(\w+?)“\w+?”将尽可能少的匹配第一个“d”之后的字符,结果是:“\w+?”只匹配了一个“x”HYPERLINK"http://www.regexlab.com/zh/workshop.asp?pat=(d)(%5Cw%2B%3F)(d)&txt=dxxxdxxxd"(d)(\w+?)(d)为了让整个表达式匹配成功,“\w+?”不得不匹配“xxx”才可以让后边的“d”匹配,从而使整个表达式匹配成功。因此,结果是:“\w+?”匹配“xxx”更多的情况,举例如下:举例1:表达式“(.*)”与字符串“

aa

bb

”匹配时,匹配的结果是:成功;匹配到的内容是“

aa

bb

”整个字符串,表达式中的“”将与字符串中最后一个“”匹配。举例2:相比之下,表达式“(.*?)”匹配举例1中同样的字符串时,将只得到“

aa

”,再次匹配下一个时,可以得到第二个“

bb

”。2.2反向引用\1,\2...表达式在匹配时,表达式引擎会将小括号“()”包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。比如前面的“(.*?)”。其实,“小括号包含的表达式所匹配到的字符串”不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面“括号内的子匹配已经匹配到的字符串”。引用方法是“\”加上一个数字。“\1”引用第1对括号内匹配到的字符串,“\2”引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号“(”在前,那这一对就先排序号。举例如下:举例1:表达式“('|")(.*?)(\1)”在匹配“'Hello',"World"”时,匹配结果是:成功;匹配到的内容是:“'Hello'”。再次匹配下一个时,可以匹配到“"World"”。举例2:表达式“(\w)\1{4,}”在匹配“aabbbbabcdefgccccc111121111999999999”时,匹配结果是:成功;匹配到的内容是“ccccc”。再次匹配下一个时,将得到999999999。这个表达式要求“\w”范围的字符至少重复5次,注意与“\w{5,}”之间的区别。举例3:表达式“<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?”在匹配“”时,匹配结果是成功。如果“”与“”不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。2.3预搜索,不匹配;反向预搜索,不匹配前面的章节中,本书讲到了几个代表抽象意义的特殊符号:“^”,“$”,“\b”。它们都有一个共同点,那就是:它们本身不匹配任何字符,只是对“字符串的两头”或者“字符之间的缝隙”附加了一个条件。理解到这个概念以后,本节将继续介绍另外一种对“两头”或者“缝隙”附加条件的,更加灵活的表示方法。正向预搜索:“(?=xxxxx)”,“(?!xxxxx)”格式:“(?=xxxxx)”,在被匹配的字符串中,它对所处的“缝隙”或者“两头”附加的条件是:所在缝隙的右侧,必须能够匹配上xxxxx这部分的表达式。因为它只是在此作为这个缝隙上附加的条件,所以它并不影响后边的表达式去真正匹配这个缝隙之后的字符。这就类似“\b”,本身不匹配任何字符。“\b”只是将所在缝隙之前、之后的字符取来进行了一下判断,不会影响后边的表达式来真正的匹配。举例1:表达式“Windows(?=NT|XP)”在匹配“Windows98,WindowsNT,Windows2000”时,将只匹配“WindowsNT”中的“Windows”,其他的“Windows”字样则不被匹配。举例2:表达式“(\w)((?=\1\1\1)(\1))+”在匹配字符串“aaaffffff999999999”时,将可以匹配6个“f”的前4个,可以匹配9个“9”的前7个。这个表达式可以读解成:重复4次以上的字母数字,则匹配其剩下最后2位之前的部分。当然,这个表达式可以不这样写,在此的目的是作为演示之用。格式:“(?!xxxxx)”,所在缝隙的右侧,必须不能匹配xxxxx这部分表达式。举例3:表达式“((?!\bstop\b).)+”在匹配“fdjkaljfdlstopfjdslafdj”时,将从头一直匹配到“stop”之前的位置,如果字符串中没有“stop”,则匹配整个字符串。举例4:表达式“do(?!\w)”在匹配字符串“done,do,dog”时,只能匹配“do”。在本条举例中,“do”后边使用“(?!\w)”和使用“\b”效果是一样的。反向预搜索:“(?<=xxxxx)”,“(?”等。本节将要讨论的是,想办法把有嵌套的的成对括号或者成对标签匹配出来。1.1匹配未知层次的嵌套有的正则表达式引擎,专门针对这种嵌套提供了支持。并且在栈空间允许的情况下,能够支持任意未知层次的嵌套:比如Perl,PHP,GRETA等。在PHP和GRETA中,表达式中使用"(?R)"来表示嵌套部分。匹配嵌套了未知层次的“小括号对”的表达式写法如下:“\( ([^()] | (?R))* \)”。[Perl和PHP的示例代码]1.2匹配有限层次的嵌套对于不支持嵌套的正则表达式引擎,只能通过一定的办法来匹配有限层次的嵌套。思路如下:第一步,写一个不能支持嵌套的表达式:“\([^()]*\)”,“((?!).)*”。这两个表达式在匹配有嵌套的文本时,只匹配最内层。第二步,写一个可匹配嵌套一层的表达式:“\(([^()]|\([^()]*\))*\)”。这个表达式在匹配嵌套层数大于一时,只能匹配最里面的两层,同时,这个表达式也能匹配没有嵌套的文本或者嵌套的最里层。匹配嵌套一层的“”标签,表达式为:“((?!).|(((?!).)*))*”。这个表达式在匹配“”嵌套层数大于一的文本时,只匹配最里面的两层。第三步,找到匹配嵌套(n)层的表达式与嵌套(n-1)层的表达式之间的关系。比如,能够匹配嵌套(n)层的表达式为:   [标记头] ( [匹配[标记头]和[标记尾]之外的表达式]|[匹配n-1层的表达式])* [标记尾]回头来看前面编写的“可匹配嵌套一层”的表达式: \(([^()]|\(([^()])*\))*\)((?!).|(((?!).)*))*       PHP和GRETA的简便之处在于,匹配嵌套(n-1)层的表达式用(?R)表示:\(([^()]|(?R))*\)第四步,依此类推,可以编写出匹配有限(n)层的表达式。这种方式写出来的表达式,虽然看上去很长,但是这种表达式经过编译后,匹配效率仍然是很高的。二.非贪婪匹配的效率可能有不少的人和本人一样,有过这样的经历:当我们要匹配类似“内容”或者“[b]加粗[/b]”这样的文本时,我们根据正向预搜索功能写出这样的表达式:“([^<]|<(?!/td>))*”或者“((?!).)*”。当发现非贪婪匹配之时,恍然大悟,同样功能的表达式可以写得如此简单:“.*?”。顿时间如获至宝,凡是按边界匹配的地方,尽量使用简捷的非贪婪匹配“.*?”。特别是对于复杂的表达式来说,采用非贪婪匹配“.*?”写出来的表达式的确是简练了许多。然而,当一个表达式中,有多个非贪婪匹配时,或者多个未知匹配次数的表达式时,这个表达式将可能存在效率上的陷阱。有时候,匹配速度慢得莫名奇妙,甚至开始怀疑正则表达式是否实用。2.1效率陷阱的产生在本书第二章里,对非贪婪匹配的描述中说到:“如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整
/
本文档为【《易语言“正则表达式”详细教程》】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索