




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、易语言“正则表达式”教程本文改编自多个文档,因此如有雷同,不是巧合。“正则表达式”的应用范围越来越广,有了这个强大的工具,我们可以做很多事情,如搜索一句话中某个特定的数据,屏蔽掉一些非法贴子的发言,网页中匹配特定数据,代码编辑框中字符的高亮等等,这都可以用正则表达式来完成。本书分为四个部分。第一部分介绍了易语言的正则表达式支持库,在这里,大家可以了解第一个正则表达式的易语言程序写法,以及一个通用的小工具的制作。第二部分介绍了正则表达式的基本语法,大家可以用上述的小工具进行试验。第三部分介绍了用易语言写的正则表达式工具的使用方法。这些工具是由易语言用户提供的,有的工具还带有易语言源码。他们是:m
2、onkeycz、零点飞越、寻梦。第四部分介绍了正则表达式的高级技巧。目 录易语言“正则表达式”教程1目 录1第一章 易语言正则表达式入门3一与DOS下的通配符类似3二初步了解正则表达式的规定3三一个速查列表4四正则表达式支持库的命令54.1 第1个正则表达式程序54.2 第2个正则表达式例程74.3 第3个例程84.4 一个小型的正则工具9第二章 揭开正则表达式的神秘面纱11引 言12一. 正则表达式规则121.1 普通字符121.2 简单的转义字符131.3 能够与“多种字符”匹配的表达式141.4 自定义能够匹配“多种字符”的表达式161.5 修饰匹配次数的特殊符号171.6 其他一些代表
3、抽象意义的特殊符号20二. 正则表达式中的一些高级规则212.1 匹配次数中的贪婪与非贪婪212.2 反向引用 1, 2.232.3 预搜索,不匹配;反向预搜索,不匹配24三. 其他通用规则25四. 其他提示27第三章 正则表达式工具与实例28一正则表达式支持库291.1 “正则表达式”数据类型291.2 “搜索结果”数据类型30二正则表达式实用工具302.1 一个成品工具302.2 易语言写的工具33三应用实例343.1 实例343.2 实例363.3 实例3373.4 实例437第四章 正则表达式话题38引 言38一. 表达式的递归匹配381.匹配未知层次的嵌套381.2 匹配有限层次的嵌
4、套39二. 非贪婪匹配的效率40. 效率陷阱的产生40. 效率陷阱的避免41附录:42一17种常用正则表达式42第一章 易语言正则表达式入门一与DOS下的通配符类似其实,所谓的“正则表达式”,是大家一直在使用的,记得吗?在搜索文件时,会使用一种威力巨大的武器DOS通配符“?”和“*”。这就是最常用的正则表达式。例如:123.* 表示所有文件名为123的文件,如123.txt, 123.doc, 123.wps, 123.swf, 123.xls等。“中国?.doc”表示所有文件名类似于 中国1.doc、中国2.doc、中国x.doc 这样的文件。上述DOS下的通配符用“?”号代表一个字符,“*
5、”号代表任意个字符,但在正则表达式中,可能这些都有些改变。如“*”号匹配的就不一样。下面看看正则表达式是如何规定的吧。二初步了解正则表达式的规定正则表达式正是在“DOS通配符”基础上复杂化而得到的。其最常用的表达式可能是:* 匹配0或多个正好在它之前的那个字符。例如a*意味着能够匹配任意数量的a字符. 匹配任何单个字符。例如r.t匹配这些字符串:rat、rut、r t,但是不匹配root(等同于DOS通配符下的?号。) 匹配一行的开始。例如When 能够匹配字符串"When in the course of human events"的开始,但是不能匹配"What
6、 and When in the"。$ 匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"They are a bunch of weasels."。 在这些字符中,可以使用 . 来表示 . ,* 表示 * ,不过,这种情况出现得很少,如果不能理解,可以暂时不理它,到用的时候就明白了。正则表达式还有一个强大的符号: ,这个 所括的内容,可以不按顺序进行匹配。如abc 匹配abc, acb, bac, bca, cab, cba这6个文本0-9 匹配任意0到9的数字a-z
7、匹配所有小写字母A-Z 匹配所有大写字母当然,你可以把它们混在一起写成a-z0-9这种样子。很多时候,我们需要检查文本中的非数字,我们就可以使用 这个符号,表示“除了”0-9 匹配所有非数字文本a-zA-Z 匹配所有非字母的文本FONT 匹配所有不含FONT的文本三一个速查列表下面用一个表来表示:*前面元素出现0次以上.匹配任何单个字符?前面元素出现0次或1次+前面元素出现1次以上表示开头。$表示结尾。.*表示0个以上的任意字符。 范围描述符。a-z表示从a到z之间的任意一个。w英文字母和数字。即0-9 A-Z a-z。W非英文字母和数字s空字符,即tnrf。S 非空字符。d数字,即0-9。D
8、非数字。b词边界字符(在范围描述符外部时)B非词边界字符b退格符(0x08)(在范围描述符内部时)m,n前面元素最少出现m次,最多出现n次|选择( )群组其他字符该字符本身四正则表达式支持库的命令基本的规则这些也就够了。下面将讲一讲易语言中正则表达式的数据类型和几个相关命令,相关的数据类型有两个:正则表达式和搜索结果。如下图所示:4.1 第1个正则表达式程序新建一个易语言程序,界面设计如下图所示:按钮被单击事件代码如下:.局部变量 正则表达式1, 正则表达式正则表达式1.创建 (“A.C”, 假)编辑框2.内容 到文本 (正则表达式1.匹配 (编辑框1.内容)如下图所示:在这里,“正则表达式1
9、”是一个正则对象,使用“创建”方法建议了一个“A.C”正则表达式,然后与编辑框1中的内容进行正则比较,最后得出结论。运行后,大家只要输入三个字符,前为A后为C都会返回真。如下图所示:但如果是小写或多于三个字符,那么返回就会是假。如下图所示:大家也许会问,这样匹配有意义吗?我只能说,有没有意义只在于你怎么用了,如:可用于程序加密时,不采用判断语句,也不采用循环语句,而是用正则去匹配是否注册成功,以及可以进行程序名称的检查,程序中一些文字的检查等,这可能让一些不会正则的破解者很难下手。4.2 第2个正则表达式例程通过第一个正则程序,大家会了解正则匹配的重要性,也了解了易语言正则支持库的基本使用方法
10、,下面这个例程可以让大家了解正则会返回一些更多的内容,大家如何去取回这些信息呢。下面改动上述程序中的一些代码为以下:.局部变量 正则表达式1, 正则表达式.局部变量 搜索结果1, 搜索结果, , "0"正则表达式1.创建 (“A.C”, 假)搜索结果1 正则表达式1.搜索全部 (编辑框1.内容)编辑框2.内容 搜索结果1 1.取匹配文本 (编辑框1.内容, )改动后如下所示:在这里,增加了一个搜索结果的对象,用这个对象接收正则表达式匹配的结果,然后从中提取出大家想要的数据。上述易语言代码的运行结果如下图所示:改动上面编辑框的内容后,结果如下:这次是较为重要的一环,即我们知道
11、了取回的内容。即由A和C包含的内容。以及下面会论述到的位置信息。取回的包含的内容意义重大,如:可以取回一对括号内的内容,这也是为了查找的方便。4.3 第3个例程这次的工作任务是取一批文字中的所有字母与数字内容。按钮被单击事件代码如下:.局部变量 正则表达式1, 正则表达式.局部变量 搜索结果1, 搜索结果, , "0".局部变量 数组索引, 整数型正则表达式1.创建 (“a-z0-9” #换行符 “”, 假)' 中间的内容,就是要搜索的内容,可以是任意字符,包括换行、空格、特殊符号.但注意如果有字符"",就表示"除了",如&q
12、uot;abc"表示"除了abc",现在,我们给出的表达式意思是匹配含字母、数字、换行符的文本,后面那个"假"意思是不区分大小写,你写成真也没有问题。搜索结果1 正则表达式1.搜索全部 (编辑框1.内容)' 搜索结果是个数组,实际上存放的是字符串搜索后的各种参数,例如位置等, 可以用"取匹配文本(,)"方法将其取出,注意它的第一个参数必须和"搜索全部()"的参数一致编辑框2.内容 “”.计次循环首 (取数组成员数 (搜索结果1), 数组索引) 编辑框2.加入文本 (搜索结果1 数组索引.取匹配文本
13、 (编辑框1.内容, ).计次循环尾 ()图片如下所示:运行后,大家可以在上面的编辑框中输入中文与字母数字的混合,点击按钮后,就可以从中提取出字母与数字了。运行效果如下图所示:4.4 一个小型的正则工具在这里,大家将学会制作一个小型的正则表达式工具,使用这个工具进行下面章节更加细致的学习。这个例程也可以在本书的随书光盘中找到。程序界面如下所示安排:按钮被单击事件的代码如下:.局部变量 正则表达式1, 正则表达式.局部变量 搜索结果1, 搜索结果, , "0".局部变量 位置1, 整数型正则表达式1.创建 (组合框1.内容, 假).如果真 (正则表达式1.是否为空 () 真)
14、 连续赋值 (“”, 编辑框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.内
15、容)编辑框D.内容 到文本 (取文本长度 (编辑框A.内容)抓图如下:通过上述代码后,运行效果如下:上述是测试“匹配”方法中注释的内容:正则表达式.创建 (“易语言4.0(模块|支持库)?”)信息框 (正则表达式.匹配 (“易语言4.0支持库”), 0, )在第二章中,大家会发现本书大量用到了这个小程序。请置这个程序的启动窗口总在最前。注意:下标从0开始还是从1开始,因当前编程语言的不同而可能不同。第二章 揭开正则表达式的神秘面纱原创文章,转载请保留或注明出处:引 言正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来:(1)检查一个串中是否含有符合某个规则的
16、子串,并且可以得到这个子串;(2)根据匹配规则对字符串进行灵活的替换操作。正则表达式学习起来其实是很简单的,不多的几个较为抽象的概念也很容易理解。之所以很多人感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难;另一方面,各种引擎自带的文档一般都要介绍它特有的功能,然而这部分特有的功能并不是大家首先要理解的。一. 正则表达式规则1.1 普通字符 字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是“普通字符”。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。举
17、例1:表达式“c”,在匹配字符串“abcde”时,匹配结果是:成功;匹配到的内容是:“c”;匹配到的位置是:开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)举例2:表达式“bcd”,在匹配字符串“abcde”时,匹配结果是:成功;匹配到的内容是:“bcd”;匹配到的位置是:开始于1,结束于4。1.2 简单的转义字符 一些不便书写的字符,采用在前面加 "" 的方法。这些字符其实我们都已经熟知了。表达式可匹配r, n代表回车和换行符t制表符代表 "" 本身
18、0; 还有其他一些在后边章节中有特殊用处的标点符号,在前面加“”后,就代表该符号本身。比如:, $ 都有特殊意义,如果要想匹配字符串中“”和“$”字符,则表达式就需要写成“”和“$”。表达式可匹配匹配 符号本身$匹配 $ 符号本身.匹配小数点(.)本身这些转义字符的匹配方法与“普通字符”是类似的。也是匹配与之相同的一个字符。举例1:表达式“$d”,在匹配字符串“abc$de”时,匹配结果是:成功;匹配到的内容是:“$d”;匹配到的位置是:开始于3,结束于5。1.3 能够与“多种字符”匹配的表达式 正则表达式中的一些表示方法,可以匹配“多种字符”其中的任意一个
19、字符。比如,表达式“d”可以匹配任意一个数字。虽然可以匹配其中任意字符,但是只能是一个,不是多个。这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。表达式可匹配d任意一个数字,09 中的任意一个w任意一个字母或数字或下划线,也就是 AZ,az,09,_ 中任意一个s包括空格、制表符、换页符等空白字符的其中任意一个.小数点可以匹配除了换行符(n)以外的任意一个字符举例1:表达式“dd”,在匹配“abc123”时,匹配的结果是:成功;匹配到的内容是:“12”;匹配到的位置是:开始于3,结束于5。举例2:表达式“a.d”,在匹配“aaa100”时,匹配的结果是:成功;匹配到的内容是
20、:“aa1”;匹配到的位置是:开始于1,结束于4。1.4 自定义能够匹配“多种字符”的表达式 使用方括号 包含一系列字符,能够匹配其中任意一个字符。用 包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。表达式可匹配ab5匹配 "a" 或 "b" 或 "5" 或 ""abc匹配 "a","b","c" 之外的任意一个字符f-k匹配 "f"
21、;"k" 之间的任意一个字母A-F0-3匹配 "A""F","0""3" 之外的任意一个字符举例1:表达式“bcdbcd”匹配“abc123”时,匹配的结果是:成功;匹配到的内容是:“bc”;匹配到的位置是:开始于1,结束于3。举例2:表达式“abc”匹配“abc123”时,匹配的结果是:成功;匹配到的内容是:“1”;匹配到的位置是:开始于3,结束于4。1.5 修饰匹配次数的特殊符号前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。
22、如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。使用方法是:“次数修饰”放在“被修饰的表达式”后边。比如:“bcdbcd” 可以写成“bcd2”。表达式作用n表达式重复n次,比如:"w2" 相当于 "ww";"a5" 相当于 "aaaaa"m,n表达式至少重复m次,最多重复n次,比如:"ba1,3"可以匹配 "ba"或"baa"或"baaa"m,表达式至少重复m次,比如:"wd2,"
23、可以匹配 "a12","_456","M12344".?匹配表达式0次或者1次,相当于 0,1,比如:"acd?"可以匹配 "a","ac","ad"+表达式至少出现1次,相当于 1,,比如:"a+b"可以匹配 "ab","aab","aaab".*表达式不出现或出现任意次,相当于 0,,比如:"*b"可以匹配 "b","b&q
24、uot;.举例1:表达式“d+.?d*”在匹配“It costs $12.5”时,匹配的结果是:成功;匹配到的内容是:“12.5”;匹配到的位置是:开始于10,结束于14。举例2:表达式“go2,8gle”在匹配“Ads by goooooogle”时,匹配的结果是:成功;匹配到的内容是:“goooooogle”;匹配到的位置是:开始于7,结束于17。想取得某个网址的匹配可以如下:哈哈,越来越有意思了吧,如果在一句话中找到某个网址也是非常简单的了,如下图所示:1.6 其他一些代表抽象意义的特殊符号一些符号在表达式中代表抽象的特殊意义:表达式作用与字符串开始的地方匹配,不匹配任何字符$与字符串结
25、束的地方匹配,不匹配任何字符b匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。举例1:表达式 "aaa" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。因为 "" 要求与字符串开始的地方匹配,因此,只有当 "aaa" 位于字符串的开头的时候,"aaa" 才能匹配,比如:"aaa xxx xxx"。举例2:表达式 "aaa$" 在匹配 "xxx aaa xxx"
26、 时,匹配结果是:失败。因为 "$" 要求与字符串结束的地方匹配,因此,只有当 "aaa" 位于字符串的结尾的时候,"aaa$" 才能匹配,比如:"xxx xxx aaa"。举例3:表达式 ".b." 在匹配 "abc" 时,匹配结果是:成功;匹配到的内容是:"a";匹配到的位置是:开始于2,结束于4。进一步说明:"b" 与 "" 和 "$" 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处
27、位置的左右两边,其中一边是 "w" 范围,另一边是 非"w" 的范围。举例4:表达式“bendb”在匹配“weekend,endfor,end”时,匹配结果是:成功;匹配到的内容是:“end”;匹配到的位置是:开始于15,结束于18。 一些符号可以影响表达式内部的子表达式之间的关系:表达式作用|左右两边表达式之间 "或" 关系,匹配左边或者右边( )(1). 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰(2). 取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到举例5:表达式 &
28、quot;Tom|Jack" 在匹配字符串 "I'm Tom, he is Jack" 时,匹配结果是:成功;匹配到的内容是:"Tom";匹配到的位置是:开始于4,结束于7。匹配下一个时,匹配结果是:成功;匹配到的内容是:"Jack";匹配到的位置时:开始于15,结束于19。举例6:表达式 "(gos*)+" 在匹配 "Let's go go go!" 时,匹配结果是:成功;匹配到内容是:"go go go";匹配到的位置是:开始于6,结束于14。举
29、例7:表达式 "¥(d+.?d*)" 在匹配 "10.9,¥20.5" 时,匹配的结果是:成功;匹配到的内容是:"¥20.5";匹配到的位置是:开始于6,结束于10。单独获取括号范围匹配到的内容是:"20.5"。二. 正则表达式中的一些高级规则2.1 匹配次数中的贪婪与非贪婪在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"m,n", "m,", "?", "*", "+",
30、具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 "dxxxdxxxd",举例如下:表达式匹配结果(d)(w+)“w+”将匹配第一个“d”之后的所有字符“xxxdxxxd”(d)(w+)(d)“w+”将匹配第一个“d”和最后一个“d”之间的所有字符 “xxxdxxx”。虽然“w+”也能够匹配上最后一个“d”,但是为了使整个表达式匹配成功,“w+”可以“让出”它本来能够匹配的最后一个“d”由此可见,“w+”在匹配的时候,总是尽可能多的匹配符合它规则的字符。虽然第二个举例中,它没有匹配最后一个“d”,但那也是为了让
31、整个表达式能够匹配成功。同理,带“*”和“m,n”的表达式都是尽可能地多匹配,带“?”的表达式在可匹配可不匹配的时候,也是尽可能的“要匹配”。这种匹配原则就叫作“贪婪”模式 。非贪婪模式:在修饰匹配次数的特殊符号后再加上一个“?”号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的“不匹配”。这种匹配原则叫作“非贪婪”模式,也叫作“勉强”模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。举例如下,针对文本“dxxxdxxxd”举例:表达式匹配结果(d)(w+?)“w+?”将尽可能少的匹配第一
32、个“d”之后的字符,结果是:“w+?”只匹配了一个“x”(d)(w+?)(d)为了让整个表达式匹配成功,“w+?”不得不匹配“xxx”才可以让后边的“d”匹配,从而使整个表达式匹配成功。因此,结果是:“w+?”匹配“xxx”更多的情况,举例如下:举例1:表达式“<td>(.*)</td>”与字符串“<td><p>aa</p></td> <td><p>bb</p></td>”匹配时,匹配的结果是:成功;匹配到的内容是“<td><p>aa</p>
33、;</td> <td><p>bb</p></td>”整个字符串, 表达式中的“</td>”将与字符串中最后一个“</td>”匹配。 举例2:相比之下,表达式“<td>(.*?)</td>”匹配举例1中同样的字符串时,将只得到“<td><p>aa</p></td>”,再次匹配下一个时,可以得到第二个“<td><p>bb</p></td>”。2.2 反向引用 1, 2.表达式在匹配时,表达式引擎会
34、将小括号“( )”包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。比如前面的“<td>(.*?)</td>”。其实,“小括号包含的表达式所匹配到的字符串”不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面“括号内的子匹配已经匹配到的字符串”。引用方法是“”加上一个数字。“1”引用第1对括号内匹配到的字符串,“2” 引用第2对括号内匹配到的
35、字符串以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号“(”在前,那这一对就先排序号。举例如下:举例1:表达式“('|")(.*?)(1)”在匹配“ 'Hello', "World"”时,匹配结果是:成功;匹配到的内容是:“'Hello'”。再次匹配下一个时,可以匹配到“"World"”。举例2:表达式“(w)14,”在匹配“aa bbbb abcdefg ccccc 111121111 999999999”时,匹配结果是:成功;匹配到的内容是“ccccc”。再次匹配
36、下一个时,将得到 999999999。这个表达式要求“w”范围的字符至少重复5次,注意与“w5,”之间的区别。举例3:表达式“<(w+)s*(w+(=('|").*?4)?s*)*>.*?</1>”在匹配“<td id='td1' style="bgcolor:white"></td>”时,匹配结果是成功。如果“<td>”与“</td>”不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。2.3 预搜索,不匹配;反向预搜索,不匹配前面的章节中,本书讲到了几个代表抽象
37、意义的特殊符号:“”,“$”,“b”。它们都有一个共同点,那就是:它们本身不匹配任何字符,只是对“字符串的两头”或者“字符之间的缝隙”附加了一个条件。理解到这个概念以后,本节将继续介绍另外一种对“两头”或者“缝隙”附加条件的,更加灵活的表示方法。正向预搜索:“(?=xxxxx)”,“(?!xxxxx)”格式:“(?=xxxxx)”,在被匹配的字符串中,它对所处的“缝隙”或者“两头”附加的条件是:所在缝隙的右侧,必须能够匹配上 xxxxx 这部分的表达式。因为它只是在此作为这个缝隙上附加的条件,所以它并不影响后边的表达式去真正匹配这个缝隙之后的字符。这就类似“b”,本身不匹配任何字符。“b”只是
38、将所在缝隙之前、之后的字符取来进行了一下判断,不会影响后边的表达式来真正的匹配。举例1:表达式“Windows (?=NT|XP)”在匹配“Windows 98, Windows NT, Windows 2000”时,将只匹配“Windows NT”中的“Windows”,其他的“Windows”字样则不被匹配。举例2:表达式“(w)(?=111)(1)+”在匹配字符串“aaa ffffff 999999999”时,将可以匹配6个“f”的前4个,可以匹配9个“9”的前7个。这个表达式可以读解成:重复4次以上的字母数字,则匹配其剩下最后2位之前的部分。当然,这个表达式可以不这样写,在此的目的是作
39、为演示之用。格式:“(?!xxxxx)”,所在缝隙的右侧,必须不能匹配 xxxxx 这部分表达式。举例3:表达式“(?!bstopb).)+”在匹配“fdjka ljfdl stop fjdsla fdj”时,将从头一直匹配到“stop”之前的位置,如果字符串中没有“stop”,则匹配整个字符串。举例4:表达式“do(?!w)”在匹配字符串“done, do, dog”时,只能匹配“do”。在本条举例中,“do”后边使用“(?!w)”和使用“b”效果是一样的。反向预搜索:“(?<=xxxxx)”,“(?<!xxxxx)”这两种格式的概念和正向预搜索是类似的,反向预搜索要求的条件是:
40、所在缝隙的“左侧”,两种格式分别要求必须能够匹配和必须不能够匹配指定表达式,而不是去判断右侧。与“正向预搜索”一样的是:它们都是对所在缝隙的一种附加条件,本身都不匹配任何字符。举例5:表达式“(?<=d4)d+(?=d4)”在匹配“”时,将匹配除了前4个数字和后4个数字之外的中间8个数字。由于 JScript.RegExp 不支持反向预搜索,因此,本条举例不能够进行演示。很多其他的引擎可以支持反向预搜索,比如:Java 1.4 以上的 java.util.regex 包,.NET 中System.Text.RegularExpressions 命名空间,以及本站推荐的最简单易用的 DEE
41、LX 正则引擎。三. 其他通用规则还有一些在各个正则表达式引擎之间比较通用的规则,在前面的讲解过程中没有提到。3.1 表达式中,可以使用“xXX”和“uXXXX”表示一个字符(“X”表示一个十六进制数)形式字符范围xXX编号在 0 255 范围的字符,比如:空格可以使用“x20”表示uXXXX任何字符可以使用“u”再加上其编号的4位十六进制数表示,比如:“u4E2D”3.2 在表达式 "s","d","w","b" 表示特殊意义的同时,对应的大写字母表示相反的意义表达式可匹配S匹配所有非空白字符("s&q
42、uot; 可匹配各个空白字符)D匹配所有的非数字字符W匹配所有的字母、数字、下划线以外的字符B匹配非单词边界,即左右两边都是 "w" 范围或者左右两边都不是 "w" 范围时的字符缝隙3.3 在表达式中有特殊意义,需要添加“”才能匹配该字符本身的字符汇总字符说明匹配输入字符串的开始位置。要匹配 "" 字符本身,请使用 ""$匹配输入字符串的结尾位置。要匹配 "$" 字符本身,请使用 "$"( )标记一个子表达式的开始和结束位置。要匹配小括号,请使用 "("
43、和 ")" 用来自定义能够匹配 '多种字符' 的表达式。要匹配中括号,请使用 "" 和 "" 修饰匹配次数的符号。要匹配大括号,请使用 "" 和 "".匹配除了换行符(n)以外的任意一个字符。要匹配小数点本身,请使用 "."?修饰匹配次数为 0 次或 1 次。要匹配 "?" 字符本身,请使用 "?"+修饰匹配次数为至少 1 次。要匹配 "+" 字符本身,请使用 "+"*修饰匹配次数
44、为 0 次或任意次。要匹配 "*" 字符本身,请使用 "*"|左右两边表达式之间 "或" 关系。匹配 "|" 本身,请使用 "|"3.4 括号“( )”内的子表达式,如果希望匹配结果不进行记录供以后使用,可以使用“(?:xxxxx)”格式举例:表达式“(?:(w)1)+”匹配“a bbccdd efg”时,结果是“bbccdd”。括号“(?:)”范围的匹配结果不进行记录,因此“(w)”使用“1”来引用。3.5 常用的表达式属性设置简介:Ignorecase,Singleline,Multilin
45、e,Global表达式属性说明Ignorecase默认情况下,表达式中的字母是要区分大小写的。配置为 Ignorecase 可使匹配时不区分大小写。有的表达式引擎,把 "大小写" 概念延伸至 UNICODE 范围的大小写。Singleline默认情况下,小数点 "." 匹配除了换行符(n)以外的字符。配置为 Singleline 可使小数点可匹配包括换行符在内的所有字符。Multiline默认情况下,表达式 "" 和 "$" 只匹配字符串的开始 和结尾 位置。如:xxxxxxxxxnxxxxxxxxx配置为 Mul
46、tiline 可以使 "" 匹配 外,还可以匹配换行符之后,下一行开始前 的位置,使 "$" 匹配 外,还可以匹配换行符之前,一行结束 的位置。Global主要在将表达式用来替换时起作用,配置为 Global 表示替换所有的匹配。四. 其他提示4.1 如果想要了解高级的正则引擎还支持那些复杂的正则语法,可参见网上关于 DEELX 正则引擎的说明文档。4.2 如果要要求表达式所匹配的内容是整个字符串,而不是从字符串中找一部分,那么可以在表达式的首尾使用 "" 和 "$",比如:"d+$" 要求整个
47、字符串只有数字。4.3 如果要求匹配的内容是一个完整的单词,而不会是单词的一部分,那么在表达式首尾使用 "b",比如:使用 "b(if|while|else|void|int)b" 来匹配程序中的关键字。4.4 表达式不要匹配空字符串。否则会一直得到匹配成功,而结果什么都没有匹配到。比如:准备写一个匹配 "123"、"123."、"123.5"、".5" 这几种形式的表达式时,整数、小数点、小数数字都可以省略,但是不要将表达式写成:"d*.?d*",因为如
48、果什么都没有,这个表达式也可以匹配成功。更好的写法是:"d+.?d*|.d+"。4.5 能匹配空字符串的子匹配不要循环无限次。如果括号内的子表达式中的每一部分都可以匹配 0 次,而这个括号整体又可以匹配无限次,那么情况可能比上一条所说的更严重,匹配过程中可能死循环。虽然现在有些正则表达式引擎已经通过办法避免了这种情况出现死循环了,比如 .NET 的正则表达式,但是我们仍然应该尽量避免出现这种情况。如果我们在写表达式时遇到了死循环,也可以从这一点入手,查找一下是否是本条所说的原因。4.6 合理选择贪婪模式与非贪婪模式,参见话题讨论。4.7 或 "|" 的左
49、右两边,对某个字符最好只有一边可以匹配,这样,不会因为 "|" 两边的表达式因为交换位置而有所不同。第三章 正则表达式工具与实例第一章将易语言的正则表达式工具简单地向大家作了介绍,并且在最后给出了一个实用的小工具进行测试。在第二章中,重点介绍了正则表达式的概念,同时用这个小工具进行了验算。本章会重新回到易语言环境中,将正则表达式支持库中的所有命令都介绍给大家。在本章的后面,就会有针对性地教大家自己写工具,以及介绍几个有用的实例。一正则表达式支持库在第一章中只是简单地使用了易语言正则表达式的几个命令。在此将会向大家介绍所有的命令。同时希望大家能安装ESDN,很多例程大家都可以
50、通过这个进一步了解。1.1 “正则表达式”数据类型“创建”方法:表示创建一个正则表达式,其在第一章中已有使用。根据指定的正则表达式文本创建一个正则表达式对象。本对象中的原有内容将被释放。成功返回真;否则返回假。“是否为空”方法:测试是否已使用创建方法载入一个正则表达式了,如果已有正则表达式,返回为“真”,否则返回为“假”。“取文本”方法。测试是否已使用创建方法载入一个正则表达式了,如果已有正则表达式,返回正则表达式的文本,否则返回“空”。“匹配”方法。表示用正则表达式与被测试文本之间的完全对应关系是否成立,如果完全对应返回“真”,否则返回“假”。比如:正则表达式.创建 (“易语言4.0(模块|
51、支持库)?”) | 信息框 (正则表达式.匹配 (“易语言4.0支持库”), 0, ) 将显示“真”。“搜索”方法。使用指定的正则表达式搜索指定文本中与该表达式匹配的子文本。“替换”方法。使用指定的正则表达式搜索指定文本中与该表达式匹配的子文本,并按照指定的格式进行替换。“搜索全部”方法。使用指定的正则表达式搜索指定文本中与该表达式匹配的所有子文本。返回值包含所有的搜索结果的一维数组,数组原有内容将被销毁,维数也将根据需要做相应调整。本命令的内部是通过循环多次调用“搜索”,每次指定适当的参数,来实现搜索整个文本的。返回值数组的各个成员分别对应每次调用“搜索”的返回值。本命令可高效地一次性取得目
52、标文本中所有的匹配子文本信息。“取子表达式个数” 方法。返回该表达式中子表达式(用圆括号标记)的个数。 比如“易语言4.0(模块|支持库)?”中包含1个子表达式:“(模块|支持库)”。1.2 “搜索结果”数据类型“是否为空”方法。表示搜索结果数据类型中是否有数据,如果对象的内容为空,没有数据,那么返回“真”,否则返回“假”。“取匹配文本”方法。取得与整个正则表达式匹配的子文本。“取子匹配文本”方法。取得与正则表达式中某个子表达式匹配的子文本。二正则表达式实用工具2.1 一个成品工具在天空或华军,可以下载到一些制作好的正则表达式工具,其各有自己的优点。大家可以自己去下载一下。本书的随书光盘中也有
53、这样一个工具。一般一个正则表达式工具可能包括下面的重要部分:正则表达式工具必须的部分正则表达式区被分析的文本区可选的部分分析后的结果显示区替换文本区设置工具工具条、状态条区菜单条自动生成语言代码工具辅助生成正则表达式的工具生成代码的工个是单独一个窗口,如下图所示:此外,有的工具还提供了可以辅助生成正则表达式的工具。有时,大家下载一个正则表达式工具,运行不了,这是需要“.NET”的支持才行。2.2 易语言写的工具用易语言写一个正则表达式工具实际上也不是什么难事。在此向大家介绍一下界面,操作方法应该也是比较简单的。三应用实例3.1 实例打开随书例程:匹配中文.e,界面如下:代码如下:运行后的效果如
54、下:3.2 实例大家还是自己看代码吧。3.3 实例3大家可以下载这个贴子中的编译程序源代码,其中有一部分的接收到错误信息时,可以通过正则表达式匹配到出错行,并且定位到出错的行上。3.4 实例4在ESDN中有一个替换网页的例程,大家自己看吧。第四章 正则表达式话题原创文章,转载请保留或注明出处:引 言本文将逐步讨论一些正则表达式的使用话题。本文为第二章之后的扩展,在阅读本文之前,建议先阅读本书第二章节内容。一. 表达式的递归匹配有时候,我们需要用正则表达式来分析一个计算式中的括号配对情况。比如,使用表达式“( )* )”或者“( .*? )”可以匹配一对小括号。但是如果括号内还嵌有一层括号的话
55、,如“( ( ) )”,则这种写法将不能够匹配正确,得到的结果是“( ( )”。类似情况的还有 HTML 中支持嵌套的标签如“<font> </font>”等。本节将要讨论的是,想办法把有嵌套的的成对括号或者成对标签匹配出来。1.匹配未知层次的嵌套有的正则表达式引擎,专门针对这种嵌套提供了支持。并且在栈空间允许的情况下,能够支持任意未知层次的嵌套:比如 Perl,PHP,GRETA 等。在 PHP 和 GRETA 中,表达式中使用 "(?R)" 来表示嵌套部分。匹配嵌套了未知层次的“小括号对”的表达式写法如下:“( () |&
56、#160; (?R)* )”。Perl 和 PHP 的示例代码1.2 匹配有限层次的嵌套对于不支持嵌套的正则表达式引擎,只能通过一定的办法来匹配有限层次的嵌套。思路如下:第一步,写一个不能支持嵌套的表达式:“( ()* )”,“<font>(?!</?font>).)*</font>”。 这两个表达式在匹配有嵌套的文本时,只匹配最内层。第二步,写一个可匹配嵌套一层的表达式:“( () | ( ()* )* )”。这个表达式在匹配嵌套层数大于一时,只能匹配最里面的两层,同时,这个表达式也能匹配没有嵌套的文本或者嵌套的最里层。匹配嵌套一层的“<
57、font>”标签,表达式为:“<font>(?!</?font>).|(<font>(?!</?font>).)*</font>)*</font>”。这个表达式在匹配“<font>”嵌套层数大于一的文本时,只匹配最里面的两层。第三步,找到匹配嵌套(n)层的表达式 与 嵌套(n-1)层的表达式之间的关系。比如,能够匹配嵌套(n)层的表达式为: 标记头 ( 匹配 标记头 和 标记尾 之外的表达式 | 匹配 n-1 层的表达式 )* 标记尾回
58、头来看前面编写的“可匹配嵌套一层”的表达式:()|()*)*)<font>(?!</?font>).|(<font>(?!</?font>).)*</font>)*</font>PHP 和 GRETA 的简便之处在于,匹配嵌套(n-1)层的表达式用 (?R) 表示:()|(?R)*)第四步,依此类推,可以编写出匹配有限(n)层的表达式。这种方式写出来的表达式,虽然看上去很长,但是这种表达式经过编译后,匹配效率仍然是很高的。二. 非贪婪匹配的效率可能有不少的人和本人一样,有过这样的经历:当我们要匹配类似“<td>
59、内容</td>”或者“b加粗/b”这样的文本时,我们根据正向预搜索功能写出这样的表达式:“<td>(<|<(?!/td>)*</td>”或者 “<td>(?!</td>).)*</td>”。当发现非贪婪匹配之时,恍然大悟,同样功能的表达式可以写得如此简单:“<td>.*?</td>”。 顿时间如获至宝,凡是按边界匹配的地方,尽量使用简捷的非贪婪匹配“.*?”。特别是对于复杂的表达式来说,采用非贪婪匹配“.*?”写出来的表达式的确是简练了许多。然而,当一个表达式中,有多个非贪婪匹配时
60、,或者多个未知匹配次数的表达式时,这个表达式将可能存在效率上的陷阱。有时候,匹配速度慢得莫名奇妙,甚至开始怀疑正则表达式是否实用。. 效率陷阱的产生在本书第二章里,对非贪婪匹配的描述中说到:“如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。”具体的匹配过程是这样的:1“非贪婪部分”先匹配最少次数,然后尝试匹配“右侧的表达式”。 2如果右侧的表达式匹配成功,则整个表达式匹配结束。如果右侧表达式匹配失败,则“非贪婪部分”将增加匹配一次,然后再尝试匹配“右侧的表达式”。 3如果右侧的表达式又匹配失败,则“非贪婪部分”将再增加匹配一次。再尝试匹配“右侧的表达式”。4依此类推,最后得到的结果是“非贪婪部分”以尽可能少的匹配次数,使整个表达式匹配成功。或者最终仍然匹配失败。当一个表达式中有多个非贪婪匹配,以表达式“d(w+?)d(w+?)z”为例,对于第一个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 发生火灾时停电应急预案(3篇)
- 行政管理风险评估试题及答案
- 2025年智能化应用试题及答案
- 时空组学 数据集格式规范 编制说明
- 高考数学2024年解题思路探讨与试题及答案
- 高考数学强化课程试题及答案
- 企业火灾场景应急预案(3篇)
- 行政审批改革中的法律分析试题与答案
- 网络管理员考试知识综合试题及答案
- 厂房火灾的应急预案(3篇)
- 歌舞娱乐场所申请登记表
- GB/T 3098.6-2023紧固件机械性能不锈钢螺栓、螺钉和螺柱
- 上海市材料工程学校教师招聘考试真题2022
- 【课件】Unit+3Reading+and+Thinking+课件高中英语人教版(2019)选择性必修第四册
- 《太上感应篇》原文
- (计算机病毒论文)计算机网络安全中病毒防护技术运用
- GB/T 39866-2021建筑门窗附框技术要求
- OLT建设方案设计模版
- 11471劳动争议处理(第9章)
- 康复治疗技术运动疗法课件
- 自主探究式教学活动模式结题报告
评论
0/150
提交评论