会员注册 | 登录|微信快捷登录 QQ登录 微博登录 |帮助中心 精品学习网 专业在线学习考试资料文档分享平台

正则表达式专题

收 藏 此文档一共:18页 本文档一共被下载: 本文档被收藏:

显示该文档阅读器需要flash player的版本为10.0.124或更高!

关 键 词:
  文库屋所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
文档介绍
★★★正则表达式专题★★★ 下面我会陆续给出正则表达式使用过程中涉及到的方方面面,已完成 。 1、何谓正则表达式 正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符 串”是否符合这个特征,即一段字符串的模式。比如,表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。 正则表达式的功能非常强大,打个比方,比如在关系数据库中,SQL语言的地位是显赫的,功能 是强大的,那么在字符串处理这个领域,正则表达式可以和SQL语言在关系数据库中扮演的角色相媲 美。从我本人从事多年的软件****实践中可以感觉到,正则表达式是值得每一个从事计算机相关工作 的人去学习、掌握,我们可以从中受惠。 正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。 (2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方 便。(3)用来替换,比普通的替换更强大。(4)split字符串。 正则表达式学习起来其实是很简单的,不多的几个较为抽象的概念也很容易理解。之所以很多人 感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先 后顺序,给读者的理解带来困难;另一方面,各种引擎自带的文档一般都要介绍它特有的功能,然而 这部分特有的功能并不是我们首先要理解的。 平时的****,常常在Java和.NET平台下进行,这两个平台都提供了相应的正则表达式引擎,用起 来感觉也很好。在VBA的****中,尽管Excel中提供了很多的内置函数,帮助我们解决一些字符串处理 相关的问题,但对有些情况,用内置的函数或者编程来解决,常常会感觉到力不从心或者非常繁琐, 而用正则表达式来解决,却变得非常简单。所有我们在这里主要学习如何在VBA中使用正则表达式。 2、相关工具 工欲善其事,必先利其器,这是我们在使用正则表达式需要注意的地方,我们做任何事情,若善于利 用一些有用的辅助工具,常常可以达到事半功倍的效果。那么在使用正则表达式的时候也是一样,我 们需要一些辅助工具来帮助我们更快、更好地完整任务。我在使用了多种正则表达式辅助****工具 后,经过综合地比较、评价,最终锁定的一款利器,堪比关羽手中的“青龙偃月刀”,所向披靡。 这款利器就是 RegexBuddy,相关介绍参见 ****.regexbuddy****,这是一款共享工具,功能 上没有限制,但只能用7天,要money的,需要注册,不过大家在网上找regexbuddy 2.3.2 full 1 version。 另外,在今年8月份,对于当时最新的版本 3.0.3已被本人一不小心crack了,想用的可以给我发邮 件,linuxyf@g****il****,邮件中要注明(Office精英俱乐部)。 下面我们粗略地看一下RegexBuddy有哪些主要功能: 1、可以很容易地创建你想要的正则表达式。 2、可以帮助我们清楚地理解别人写的正则表达式的含义。 3、可以用测试字符串或者测试文件验证正则表达式是否合乎要求。 4、自动生成对应各种编程语言的程序代码段,我们只需要写出符****要求的正则表达式,对应编 程语言的代码段立刻可以生成,这一点非常的方便。 5、有一个可复用的正则表达式库,放置的都是一些经典的、常用的正则表达式供我们所用。 从上面的主要功能介绍我们可以看出,RegexBuddy绝对是我们处理正则表达式的不二选择,是 一款出色的正则表达式伴侣式工具,郑重推荐大家使用。 3、正则表达式规则------字符 3.1 普通字符 字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符****,都是"普通字符"。表达 式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。 举例1:表达式 "c",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"c";匹 配到的位置是:开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能 不同) 举例2:表达式 "bcd",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容 是:"bcd";匹配到的位置是:开始于1,结束于4。 3.2 特殊字符 因为我们不总是做简单搜索,所以需要保留一些字符用作特殊用途。有11个字符有特殊的含义, 分别是:"[", "\","^","$",".","|","?","*","+","(" 和")"。 这些特殊字符我们通常称作元字 符。 如果你想把它们作为一个普通字符来使用,需要在这些符****之前加一个转义字符"\",比如,如果 你想匹配"1+1=2",正确的模式应该是"1\+1=2",不然,加****"+"就有了特殊的含义。注 意,"1+1=2",其中的加****不带转义字符,但这也是一个有效的正则表达式,所以在程序执行的时候不 会有错误,但它不会匹配"1+1=2",因为特殊字符"+",它将会在"123+111=234"字符串中,匹 配"111=2"。 3.3 不能显示的字符 2 模式串中可以使用一些不不能显示的字符,如:用 \t 来匹配一个 tab 字符 (ASCII 0x09), \r 代表回车 (0x0D) , \n 代表换行 (0x0A). 注意windows操作系统的文本文件中,用 \r\n 分割行,而UNIX 操作系 统中使用\n. 4、正则表达式引擎的内部工作机制 了解正则表达式引擎的内部工作机制将有助于你更好地驾驭正则表达式,高效、简洁书写合理的正则 表达式来完成任务。 有两种类型的引擎:文本导向(text-directed)引擎和正则导向(regex-directed)引擎。Jeffrey Friedl把它 们称作DFA和NFA引擎。本文谈到的是正则导向引擎。因为一些非常有用的特性,如“惰性”量词(lazy quantifiers)和反向引用(backreferences),只能在正则导向的引擎中实现, 毫不意外这种引擎是目前最 流行的引擎。 你可以轻易分辨所使用的引擎是哪一种,若反向引用或“惰性”量词被实现,则可以肯定你使用的是正则 导向引擎。你可以作如下测试:将正则表达式<>应用到字符串“regex not”。如果匹 配的结果是regex,则是正则导向引擎。如果结果是regex not,则是文本导向引擎。 正则导向的引擎总是返回最左边的匹配 这是非中重要的一点:即使在后边可能发现一个“更好”的匹配,正则导向的引擎也总是返回最左边的匹 配。 当把<>应用到“He captured a catfish for his cat”,引擎先比较<>和“H”,结果失败了。于 是引擎再比较<>和“e”,也失败了。直到第四个字符,<>匹配了“c”。<>匹配了第五个字 符。到第六个字符<>没能匹配“p”,也失败了。引擎再继续从第五个字符重新检查匹配性。直到第 十五个字符开始,<>匹配上了“catfish”中的“cat”,正则表达式引擎急切的返回第一个匹配的结 果,而不会再继续查找是否有其他更好的匹配。 5、字符类或者字符集 字符类(也称为字符集)是由一对方括****“[]”括起来的字符集合。使用字符集,正则引擎可以只匹配多 个字符中的一个。如果你想匹配一个“a”或一个“e”,使用<<[ae]>>。使用<>匹配gray或 grey。在你不确定你要搜索的字符是采用美国英语还是英国英语时特别有用。一个字符集只匹配一个字 符,<>将不会匹配graay或graey。字符集中的字符顺序无关。 可以使用连字符“-”定义一个字符范围作为字符集。<<[0-9]>>匹配0到9之间的单个数字。可以使用不 3 止一个范围。<<[0-9a-fA-F] >>匹配单个的十六进制数字,并且大小写不敏感。也可以结合范围定义 与单个字符定义。<<[0-9a-fxA-FX]>>匹配一个十六进制数字或字母X。再次强调一下,字符和范围定 义的先后顺序对结果没有影响。 字符集的一些应用 查找一个可能写错的单词,比如<> 或 <>。 查找程序语言的标识符,<>。(*表示重复0或多次) 查找C风格的十六进制数<<0[xX][A-Fa-f0-9]+>>。(+表示重复一次或多次) 反字符集 在左方括****“[”后面紧跟一个尖括****“^”,将会对字符集取反。结果是字符集将匹配任何不在方括****中的 字符。不像“.”,取反字符集是可以匹配回车换行符的。 需要记住的很重要的一点是,取反字符集必须要匹配一个字符。<>并不意味着:匹配一个 q,后面没有u跟着。它意味着:匹配一个q,后面跟着一个不是u的字符。所以它不会匹配“Iraq”中的 q,而会匹配“Iraq is a country”中的q和一个空格符。事实上,空格符是匹配中的一部分,因为它是一 个“不是u的字符”。 如果只想匹配一个q,条件是q后面有一个不是u的字符,可以用后面将讲到的向前查看来解决。 字符集中的元字符 需要注意的是,在字符集中只有4个 字符具有特殊含义。它们是:“] \ ^ -”。“]”代表字符集定义的结 束;“\”代表转义;“^”代表取反;“-”代表范围定义。其他常见的元字符在字符集定义内部都是正常字 符,不需要转义。例如,要搜索星*****或加****+,你可以用<<[+*]>>。当然,如果你对那些通常的元 字符进行转义,你的正则表达式一样会工作得很好,但是这会降低可读性。 在字符集定义中为了将反斜杠“\”作为一个文字字符而非特殊含义的字符,你需要用另一个反斜杠对它 进行转义。<<[\\x]>>将会匹配一个反斜杠和一个X。“]^-”都可以用反斜杠进行转义,或者将他们放在 一个不可能使用到他们特殊含义的位置。我们推荐后者,因为这样可以增加可读性。比如对于字符 “^”,将它放在除了左括****“[”后面的位置,使用的都是文字字符含义而非取反含义。如<<[x^]>>会匹 配一个x或^。<<[]x]>>会匹配一个“]”或“x”。<<[-x]>>或<<[x-]>>都会匹配一个“-”或“x”。 字符集的简写 因为一些字符集非常常用,所以有一些简写方式。 <<\d>>代表<<[0-9]>>; <<\w>>代表单词字符。这个是随正则表达式实现的不同而有些差异。绝大多数的正则表达式实现的 单词字符集都包含了<>。 4 <<\s>>代表“白字符”。这个也是和不同的实现有关的。在绝大多数的实现中,都包含了空格符和Tab 符,以及回车换行符<<\r\n>>。 字符集的缩写形式可以用在方括****之内或之外。<<\s\d>>匹配一个白字符后面紧跟一个数字。<<[\s \d]>>匹配单个白字符或数字。<<[\da-fA-F]>>将匹配一个十六进制数字。 取反字符集的简写 <<[\S]>> = <<[^\s]>> <<[\W]>> = <<[^\w]>> <<[\D]>> = <<[^\d]>> 字符集的重复 如果用“?*+”操作符来重复一个字符集,将会重复整个字符集。而不仅是它匹配的那个字符。正则表达 式<<[0-9]+>>会匹配837以及222。 如果仅仅想重复被匹配的那个字符,可以用向后引用达到目的。以后将讲到向后引用。 6、点****"." 使用“.”匹配几乎任意字符 在正则表达式中,“.”是最常用的元字符之一。不幸的是,它也容易被误用。 “.”匹配一个单个的字符而不管该字符是什么。唯一的例外是换行符。在本教程中谈到的引擎,缺省情况 下都是不匹配换行符的。因此在缺省情况下,“.”等价于字符集[^\n\r](Window)或[^\n]( Unix)。 这个例外是有历史原因的,因为早期使用正则表达式的工具是基于行的,它们都是一行一行的读入一 个文件,将正则表达式分别应用到每一行上去,在这些工具中,字符串是不包含换行符的。因此“.”也就 从不匹配换行符。 现代的工具和语言能够将正则表达式应用到很大的字符串甚至整个文件上去。在Perl中,“.”可以匹配换 行符的模式被称作“单行模式”。很不幸,这是一个很容易混淆的名词。因为还有所谓“多行模式”。多行 模式只影响行首行尾的锚定(anchor),而单行模式只影响“.”。 其他语言和正则表达式库也采用了Perl的术语定义。当在.NET Framework中使用正则表达式类时,你 可以用类似下面的语句来激活单行模式:Regex.Match(“string”,”regex”,RegexOptions.SingleLine) 保守地使用点****“.” 点****可以说是最强大的元字符。它允许你偷懒:用一个点****,就能匹配几乎所有的字符。但是问题在 5 于,它也常常会匹配不该匹配的字符。 以一个简单的例子来说明。如何匹配一个具有“mm/dd/yy”格式的日期,想允许用户来选择分隔符。很 快能想到的一个方案是<<\d\d.\d\d.\d\d>>。看上去它能匹配日期“02/12/03”。问题在于02512703也 会被认为是一个有效的日期。 <<\d\d[-/.]\d\d[-/.]\d\d>>看上去是一个好一点的解决方案。记住点****在一个字符集里不是元字符。 这个方案远不够完善,它会匹配“99/99/99”。而<<[0-1]\d[-/.][0-3]\d[-/.]\d\d>>又更进一步。尽管他 也会匹配“19/39/99”。你想要你的正则表达式达到如何完美的程度取决于你想达到什么样的目的。如果 你想校验用户输入,则需要尽可能的完美。如果你只是想****一个已知的源,并且我们知道没有错误 的数据,用一个比较好的正则表达式来匹配你想要搜寻的字符就已经足够。 工欲善其事,必先利其器 The Python Regular Expression Debugger http://kodos.sourceforge****/ 7、锚(anchor) 字符串开始和结束锚(anchor) 锚是一个特别的符****,它不匹配任何字符。相反,他们匹配的是字符之前或之后的位置。“^”匹配一行 字符串第一个字符前的位置。<<^a>>将会匹配字符串“abc”中的a。<<^b>>将不会匹配“abc”中的任 何字符。 类似的,$匹配字符串中最后一个字符后面的位置。所以<>匹配“abc”中的c。 应用场合 在编程语言中校验用户输入时,使用锚是非常重要的。如果你想校验用户的输入为整数,用 <<^\d+$>>。 用户输入中,常常会有多余的前导空格或结束空格。你可以用<<^\s*>>和<<\s*$>>来匹配前导空格 或结束空格。 使用“^”和“$”作为行的开始和结束锚 如果有一个多行的字符串。例如:“first line\r\nsecond line”(其中\r\n表示一个换行符)。常常需要逐行 处理而不是处理整个字符串。因此,几乎所有的正则表达式引擎都提供一个选项,可以扩展这两种锚 的含义。“^”可以匹配字串的开始位置(在f之前),以及每一个换行符的后面位置(在\r\n和s之间)。类似 的,$会匹配字串的结束位置(最后一个e之后),以及每个新行符的前面(在e与\r\n之间)。 6 在.NET中,当你使用如下代码时,将会定义锚匹配每一个换行符的前面和后面位 置:Regex.Match("string", "regex", RegexOptions.Multiline) ;string str = Regex.Replace(Original, "^", "> ", RegexOptions.Multiline)--将会在每行的行首插入“> ”。 字符串绝对开始和结束锚(anchor) <<\A>>只匹配整个字符串的开始位置,<<\Z>>只匹配整个字符串的结束位置。即使你使用了“多行 模式”,<<\A>>和<<\Z>>也从不匹配新行符。 8 词界 元字符<<\b>>也是一种类似于<<^>>和<<$>>的“锚”,用来匹配单词边界位置,匹配长度0。 有4种不同位置常被鉴定为“单词边界”: ● 在字符串的第一个字符前的位置(如果字符串的第一个字符是一个“单词字符”) ● 在字符串的最后一个字符后的位置(如果字符串的最后一个字符是一个“单词字符”) ● 在一个“单词字符”和“非单词字符”之间,其中“非单词字符”紧跟在“单词字符”之后 ● 在一个“非单词字符”和“单词字符”之间,其中“单词字符”紧跟在“非单词字符”后面 “单词字符”是可以用<<\w>>匹配的字符,“非单词字符”是可以用<<\W>>匹配的字符。在大多数的正 则表达式实现中,“单词字符”通常包括<<[a-zA-Z0-9_]>>。 例如:<<\b4\b>>能够匹配单个的4而不会匹配“44”中的4。可以说<<\b>>匹配一个“字母数字序列”的 开始和结束的位置。 “单词边界”的反集为<<\B>>,他要匹配的位置是两个“单词字符”之间或者两个“非单词字符”之间的位 置。 9、选择符 可以使用选择符<<|>>来匹配几个正则表达式中的一个。 如果要查找文本串“cat”或者“dog”,可以用<>。如果想有更多的选择,只要扩展列表 <>。 选择符在正则表达式中具有最低的优先级,也就是说,它告诉引擎要么匹配选择符左边的所有表达 7 式,要么匹配右边的所有表达式。可以用圆括****来限制选择符的作用范围。如<<\b(cat|dog)\b>>,这 样告诉正则引擎把(cat|dog)当成一个正则表达式单位来处理。 注意正则引擎的“Eager”性 正则引擎找到一个有效的匹配时,会停止搜索。因此在一定条件下,选择符两边的表达式的顺序对结 果会有影响。假设用正则表达式搜索一个编程语言的函数列表:Get,GetValue,Set或SetValue。一个 明显的解决方案是<>。 当搜索SetValue时的结果,因为<>和<>都失败了,而<>匹配成功。因为正 则导向的引擎的"Eager"性,所以它会返回第一个成功的匹配,就是“Set”,而不去继续搜索是否有其他 更好的匹配。和期望的相反,正则表达式并没有匹配整个字符串。有几种可能的解决办法。一是考虑 到正则引擎的“Eager”性,改变选项的顺序,例如使用<>,这样可以优 先搜索最长的匹配。也可以把四个选项结合起来成两个选项:<>。因为问 ****重复符是贪婪的,所以SetValue总会在Set之前被匹配。 一个更好的方案是使用单词边界:<<\b(Get|GetValue|Set|SetValue)\b>>或 <<\b(Get(Value)?|Set(Value)?\b>>。更进一步,既然所有的选择都有相同的结尾,可以把正则表达式 优化为<<\b(Get|Set)(Value)?\b>>。 本帖最后由 godhawk 于 2011-8-30 19:48 编辑 10、正则表达式实战训练1 光说不练也不行,在讲理论的时候得配合实战训练,效果才会更好。下面给一个例子,用来学习基本 的正则编程。 题目:要求取得字符串中的所有数字。 题目本身比较简单,我们可以采用常规的做法,从字符串的第一个字符开始,循环逐个判断每一个字 符是数字还是非数字...... 但常规做法显得比较麻烦,我们来看如何使用正则表达式来解决这个问题。 思路有二: 1. 采用查找的方式,匹配到数字就取出来,最后连成一个结果。 所用的正则表达式为 \d+,可以匹 配一个或多个连续的数字。 8 2. 采用替换的方式,匹配到非数字就把它替换成空字符串。所用的正则表达式为 [^\d]+,可以匹配一 个或多个连续的非数字。 究竟那种方式更好,大家自己判断一下就可以了,比较容易的。 程序代码及实际效果见附件 “正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串” 是否符合这个特征,即一段字符串的模式。比如,表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。” ------------ 看了这段后,我决定要学一学正则表达式。 谢谢领我这个笨学徒入门。 11、问****的使用 在正则表达式中,问****使它前面的符****变成可选项。如:<>可以匹配"colour"和"color"。 使用圆括****使一组字符成为可选项,问****在圆括****后。如:<>会匹配"Nov" 和"November"。 在一个正则表达式中,可以使用多个问****,使多个符****成为可选项。如:<>匹 配"February 23rd","February 23","Feb 23rd"和"Feb 23"。 在这里,要介绍正则表达式中的一个非常重要的概念------贪婪性。我们这里介绍的第一个贪婪的元字 符就是问****。问****让正则引擎有两种选择:尽力去匹配问****前的部分;不匹配问****钱的部分。而正则 引擎总是试图去匹配问****前的部分,只有当这样的尝试失败后,才会忽略掉问****前的部分,所以说问 ****是一个贪婪的元字符。 若用正则式<>去匹配字符串"Today is Feb 23rd, 2003",得到的结果总是"Feb 23rd"而 不是"Feb 23",就是因为问****的贪婪性。 12、重复量词 使用*和+进行重复 9 11、中已经介绍过一种重复操作符或者说量词:问****?。它告诉正则引擎匹配前导字符0次或者1次,效 果就是使它成为可选的。 +告诉引擎匹配前导字符1次或多次;*告诉引擎匹配前导字符0次或多次。 正则式 <[A-Za-z][A-Za-z0-9]*> 匹配没有属性的HTML标签,,“<”以及“>”是文字符****。第一个 字符集[A-Za-z]匹配一个字母,第二个字符集[A-Za-z0-9]匹配一个字母或数字,星****重复第二个字符集 一次或多次。因为我们使用星****,第二个字符集有0个匹配也是正确的,所以这个正则式可以匹配一个 标签""。匹配字符串""时,第一个字符集匹配"H",星****将会导致第二个字符集重复匹配三 次,匹配到"TML"。 有限重复 许多现在的正则引擎实现,允许定义对一个字符重复多少次。语法是:{min,****x}。min和****x都是非 负整数。如果逗****有而****x被忽略了,则****x没有限制。如果逗****和****x都被忽略了,则重复min次。 因此{0,}和*一样,{1,}和+ 的作用一样。 你可以用\b[1-9][0-9]{3}\b匹配1000~9999之间的数字(“\b”表示单词边界)。\b[1-9][0-9]{2,4}\b匹配一 个在100~99999之间的数字。 注意贪婪性 假设用一个正则式去匹配一个HTML标签。知道输入将会是一个有效的HTML文件,因此正则式不需要排 除那些无效的标签。所以如果是两个尖括****之间的内容,就应该是一个HTML标签。 很多正则式的新手首先会想到用正则式 <.+> ,他们会很惊讶的发现,对于测试字符串,“This is a first test”,你可能期望会返回,然后继续进行匹配的时候,返回。但事实不 会。正则式将会匹配“first”。显然这不是我们想要的结果。 原因在于“+”是贪婪的。也就是说,“+”会导致正则引擎试图尽可能地重复前导字符。只有当这种重复会 引起整个正则表达式匹配失败的情况下,引擎会进行回溯。也就是说,它会放弃最后一次的“重复”,然 后处理正则表达式余下的部分。 和“+”类似,“?”“*”的重复也是贪婪的。 13、正则表达式实战训练2 10 练习重复量词的使用 要求把一个由多个名字组成的字符串,按组成名字逆序排列。 程序代码及运行效果见附件 正则表达式中有类似"或"运算的符****:"|",可是没有类似"与"运算的符****,这是为什么呢? 另外:所有不是汉字的字符正则表达式怎么写呢? 如这样的字符串:"a b c d e f",每两个字符中间的空格可能不止一个,要把它变成"ab cd ef",空格都是一 个,正则表达式又该怎么写呢? 问题1 正则表达式中没有和“与”运算对应的符****,毕竟不是实现逻辑运算。如果你想验证一个字符串是否包含 字符串"a”且包含"b",可以这样做: Dim myRegExp, FoundMatch1, foundMatch2 Set myRegExp = New RegExp myRegExp.Pattern = "a" FoundMatch1 = myRegExp.Test(SubjectString) myRegExp.Pattern = "b" FoundMatch2 = myRegExp.Test(SubjectString) 这里判断FoundMatch1和FoundMatch2同时为True即可。 就是说与的关系可以用某种编程语言的与运算符来实现,而不是用正则中的特殊字符去表示。 14、分组与后向引用(Grouping and Backreference) 使用圆括****进行分组 把部分正则表达式置于一对圆括****内"()",可以将它们形成组。这样可以对整个组使用一些正则操 作,例如重复操作。这里需要注意的是,只有圆括****才可以用于分组, 方括****和大括****都有不同的用 途,不要混淆。 11 使用圆括****创建后向引用 “()”在分组的同时,也会创建一个“后向引用”,一个“后向引用”保存的是一个分组内正则表达式 匹配的字符串。 在定义了一个正则表达式组的同时,“()”也创建了一个后向引用。一个后向引用保存了由"()"内的正则 式匹配到的字符串。 除非你使用“非捕获”的“()”,否则该“()”会形成一个后向引用。这里记住后向引用会减慢正则引擎的速 度,因为它需要完成一些额外的操作。如果你不使用后向引用,你可以使用非捕获的“()”来提高正则引 擎的工作速度,但这样做的代价是会使你的正则式的易读性降低。 正则式"Set(Value)?"匹配"Set"或"SetValue"。在第一种情况中,第一个后向引用(这里也只有一个后向 引用)是空的,因为它没有匹配任何字符串。在第二种情况中,第一个后向引用将会保存"Value"。 如果你不使用后向引用,你可以把这个正则式优化成"Set(?:Value)?",正则式中"("后的问****和冒****是一 种特殊的语法格式,它会告诉正则引擎"()"不创建后向引用。注意这里的"("后的"?"和我们在11、中讲到 的正则表达式中的问****是不一样的,因为"("本身是一个特殊符****,不是一个有效的正则符****。 如何使用后向引用 后向引用允许你重复使用后向引用中保存的内容。可以用“\数字”的方式进行引用。"\1"引用第一个匹配 的后向引用组,"\2"引用第二个组,以此类推,"\n"引用第n个组。而"\0"则引用整个被匹配的正则表达 式本身。 在正则式中使用后向引用 假设你想匹配一个HTML标签的开始标签和结束标签,以及标签中间的文本。比如This is a test,我们要匹配以及中间的文字。我们可以用如下正则表达式:“<([A-Z][A-Z0-9]*) [^>]*>.*?” 首先,“<”将会匹配“”的第一个字符“<”。然后[A-Z]匹配B,[A-Z0-9]*将会匹配0到多次字母数字, 后面紧接着0到多个非“>”的字符。最后正则表达式的“>”将会匹配“”的“>”。接下来正则引擎将对结 束标签之前的字符进行惰性匹配,直到遇到一个“” 你可以对相同的后向引用组进行多次引用,"([a-c])x\1x\1"将匹配“axaxa”、“bxbxb”以及“cxcxc”。如果 用数字形式引用的组没有有效的匹配,则引用到的内容简单的为空。 一个后向引用不能用于它自身。"([abc]\1)"是错误的。因此你不能将"\0"用于一个正则表达式匹配本 12 身,它只能用于替换操作中。 后向引用不能用于字符集内部。"(a)[\1b]"中的"\1"并不表示后向引用。在字符集内部,"\1"可以被解释 为八进制形式的转码。 重复操作与后向引用 当对组使用重复操作符时,缓存里后向引用内容会被不断刷新,只保留最后匹配的内容。如果"()"中的 正则式找到一个新的匹配,则后向引用中的内容会被覆盖。"([abc]+) "和"([abc])+"就有着明显的差 别。对于字符串"abc",两个正则式都会匹配成功。第一个正则式将会把"abc"置于后向引用中,而第二 个正则式仅会把"b"置于后向引种中。因为在第二个正则式中,"+"会导致"()"重复匹配3次,第一次"a" 被保存,第二次"b"被保存,第三次"c"被保存,每一次,前一次的值都被覆盖。 这也意味着对于字符串"cab=cab", 正则式"([abc]+)=\1"会匹配成功,而"([abc])+=\1"则不能匹配成 功。 后向引用使用实例 当编辑文字时,很容易就会输入重复单词,例如"the the"。使用"\b(\w+)\s+\1\b"可以检测到这些重复 单词。要删除第二个单词,只要简单的利用替换功能,用"\1"替换就可以了。 15、正则表达式实战训练3 问题: 字符串中1个或者连续多个空格替换成一个Tab键 ****: 由于字符串中连续的空格的个数不太确定,如果我们逐个字符去****的话,也是比较麻烦的, 但如果用正则去实现,则简单的多。这也是一个典型的适合用正则解决的问题。解决方式如下: Sub test() As Object Dim RegEx Set RegEx = CreateObject("vbscript.regexp") With RegEx .Global = True .Pattern = "\s+" End With Range("B1").Value = RegEx.Replace(Range("A1").Text, Chr(9)) 13 Set RegEx = Nothing End Sub 16、正则表达式实战训练4 问题:查找字符串中连续9个数字字符并显示其开始位置。 Sub test() Set objRegEx = CreateObject("VBScript.RegExp") objRegEx.Global = True objRegEx.Pattern = "\d{9}" strSearchString = "aaaaaaa123456789qqqqqqqqqqqq234567891aaaa12345678" Set colMatches = objRegEx.Execute(strSearchString) If colMatches.Count > 0 Then strMessage = "The following user accounts were found:" & vbCrLf For Each strMatch In colMatches strMessage = strMessage & strMatch.Value & " (character position " & _ strMatch.FirstIndex & ")" & vbCrLf Next End If MsgBox strMessage End Sub 17、实用的正则查找封装函数 这是一个封装的查找函数,使用正则实现查找功能,函数实现如下,使用时,把下面的函数置于VBA工 程的普通模块中,就可以在代码中引用或者在单元格中直接使用函数 Function RegExpFind(LookIn As String, PatternStr As String, Optional Pos, Optional MatchCase As Boolean = True) ' This function uses Regular Expressions to parse a string (LookIn), and return ****tches to a ' pattern (PatternStr). Use Pos to indicate which ****tch you want: ' Pos omitted : function returns a zero-based array of all ****tches ' Pos = 0 : the last ****tch 14 ' Pos = 1 : the first ****tch ' Pos = 2 : the second ****tch ' Pos = : the Nth ****tch ' If Pos is greater than the number of ****tches, is negative, or is non-numeric, the function ' returns an empty string. If no ****tch is found, the function returns an empty string ' If MatchCase is omitted or True (default for RegExp) then the Pattern must ****tch case (and ' thus you ****y have to use [a-zA-Z] instead of just [a-z] or [A-Z]). ' If you use this function in Excel, you can use range references for any of the arguments. ' If you use this in Excel and return the full array, ****ke sure to set up the formula as an ' array formula. If you need the array formula to go down a column, use TRANSPOSE() Dim RegX As Object Dim TheMatches As Object Dim Answer() As String Dim Counter As Long ' Evaluate Pos. If it is there, it must be numeric and converted to Long If Not IsMissing(Pos) Then If Not IsNumeric(Pos) Then RegExpFind = "" Exit Function Else Pos = CLng(Pos) End If End If ' Create instance of RegExp object Set RegX = CreateObject("VBScript.RegExp") With RegX .Pattern = PatternStr .Global = True .IgnoreCase = Not MatchCase End With ' Test to see if there are any ****tches If RegX.test(LookIn) Then 15 ' Run RegExp to get the ****tches, which are returned as a zero-based collection Set TheMatches = RegX.Execute(LookIn) ' If Pos is missing, user wants array of all ****tches. Build it and assign it as the ' function's return value If IsMissing(Pos) Then ReDim Answer(0 To TheMatches.Count - 1) As String For Counter = 0 To UBound(Answer) Answer(Counter) = TheMatches(Counter) Next RegExpFind = Answer ' User wanted the Nth ****tch (or last ****tch, if Pos = 0). Get the Nth value, if possible Else Select Case Pos Case 0 ' Last ****tch RegExpFind = TheMatches(TheMatches.Count - 1) Case 1 To TheMatches.Count ' Nth ****tch RegExpFind = TheMatches(Pos - 1) Case Else ' Invalid item number RegExpFind = "" End Select End If ' If there are no ****tches, return empty string Else RegExpFind = "" End If ' Release object variables Set RegX = Nothing Set TheMatches = Nothing End Function 18、实用的正则替换封装函数 16 这是一个封装的替换函数,使用正则实现替换功能,函数实现如下,使用时,把下面的函数置于VBA工 程的普通模块中,就可以在代码中引用或者在单元格中直接使用函数 Function RegExpReplace(LookIn As String, PatternStr As String, Optional ReplaceWith As String = "", Optional ReplaceAll As Boolean = True, Optional MatchCase As Boolean = True) ' This function uses Regular Expressions to parse a string, and replace parts of the string ' ****tching the specified pattern with another string. The optional argument ReplaceAll controls ' whether all instances of the ****tched string are replaced (True) or just the first instance (False) ' By default, RegExp is case-sensitive in pattern-****tching. To keep this, omit MatchCase or ' set it to True ' If you use this function from Excel, you ****y substitute range references for all the arguments Dim RegX As Object Set RegX = CreateObject("VBScript.RegExp") With RegX .Pattern = PatternStr .Global = ReplaceAll .IgnoreCase = Not MatchCase End With RegExpReplace = RegX.Replace(LookIn, ReplaceWith) Set RegX = Nothing End Function 19、正则表达式实战训练5 问题:判断一个邮件地址格式是否有效 17 这是通用的正则表达式吧?word不能简单套用,规定的字符不一样,支持度也不一样。尤其是后者。 比如“$”作为行结束锚,word显然就行不通,这么做会找出一连串英文字母来,毫无用处。 偶至今都不知道word行尾的表达式是什么,谁能教教偶?…… 二楼的朋友说的是WORDS专用的通配符吧? 那个和正则貌似不是一个概念,是words专用的符****代 码, 但是word是有办法支持正则的,通过自建对象…… 都是正则,一个概念,但写法上有区别,支持的深度和广度也不一样。 Adobe InDesign中也支持正则,它那又是一套写法,支持度又不一样。 偶最初的正则学的是个什么必知必会,一个什么万达的外国人写的。 正则本来就不好学,如此各家又各搞一套,对偶们这些应用层面的人来说真是一场灾难。什么时候所 有应用软件的正则都是经典正则的模样就好了。 楼主的正则表达式,似乎与MS 自带的正则表达式是差不多吧(我没细看)。 有关MS自带的正则表达式对象(Microsoft VBScript Regular Expressions 5.5)的相关贴子可参考: http://club.excelhome****/forum.php?mod=viewthread&tid=304261 18

当前资源信息

高级会员

爱学习共有文档721 篇

编号:WENKUWU582

类型: IT/计算机

格式: pdf

大小: 0.19 MB

上传时间:2018-03-16

相关搜索

文库屋  www.wenkuwu.com (精品学习网 专业在线学习考试资料文档分享平台)

本站部分文档来自互联网收集和整理和网友分享,如果有侵犯了您的版权,请及时联系我们.
© www.topstudy.com.cn 2016-2012 精品学习网 版权所有 并保留所有权  ICP备案号:  粤ICP备14083021号-8