`
javasogo
  • 浏览: 1770225 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

简单入门正则表达式 - 第一章 概述

 
阅读更多
<style> #content-region { background-image: url(http://p.blog.csdn.net/images/p_blog_csdn_net/rcom10002/EntryImages/20081027/watermark.gif); } #content-region h3 { border: 1px dotted #333333; background-color: #f9f9f9; padding: 10px; font-size: 24px; } #content-region p { font-family: "宋体", "仿宋"; font-size: 16px; line-height: 28px; text-decoration: none; text-indent: 32px; } #content-region .regex-pattern { font-style: oblique; font-family: "Courier New", Courier, monospace; background-color: #FFCCCC; border-top-style: solid; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-top-color: #FF0000; border-bottom-color: #FF0000; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-right-color: #FF0000; border-left-color: #FF0000; padding: 0px 5px 0px 5px; } #content-region .regex-result { font-family: "Courier New", Courier, monospace; background-color: #A4FFE1; border-top-style: solid; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-top-color: #339966; border-bottom-color: #339966; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-right-color: #339966; border-left-color: #339966; padding: 0px 5px 0px 5px; } #content-region blockquote { padding: 10px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; width: auto; } #content-region img { border: 1px dotted #000000; padding: 16px; background-color: #f9f9f9; margin-top: 16px; margin-right: 16px; margin-bottom: 16px; margin-left: 64px; } #content-region code { white-space: pre; } </style>
<!-- InstanceBeginEditable name="contentRegion" -->

一、正则表达式的诞生

最初的正规表达式出现于理论计算机科学的自动控制理论和形式语言理论中。在这些领域中有对计算(自动控制)的模型和对形式语言描述与分类的研究。1940年代,Warren McCulloch与Walter Pitts将神经系统中的神经元描述成小而简单的自动控制元。稍后,数学家Stephen Kleene利用称之为正则集合的数学符号来描述此模型。Ken Thompson将此符号系统引入编辑器QED,然后是Unix上的编辑器ed,并最终引入grep。自此,正规表达式被广泛地使用于各种Unix或者类似Unix的工具。自从那时起,正则表达式经过几个时期的发展,现在的标准已经被ISO(国际标准组织)批准和被Open Group组织认定。

正则表达式并非一门专用语言,但它可看作在一个文件或字符里查找和替代文本的一种标准。它具有两种标准:基本的正则表达式(BRE),扩展的正则表达式(ERE)。ERE包括BRE功能和另外其它的概念,关于两者之间的具体关系与区别,请参考网站 www.opengroup.org。 许多应用程序中都使用了正则表达式,包括xsh,egrep,sed,vi等等。并且在目前流行的编程语言中,如Java、.Net、PHP、Rubby 和 JavaScript等,正则表达式的身影也无处不在。

二、正则表达式引擎

了解正则表达式的引擎工作机制,有助于我们更加容易、准确地构造简单或复杂的正则表达式;更重要的是我们在构造正则表达式不用靠猜测或假象去完成它。正则表达式引擎分成两类,一类称为 DFA (确定性有穷自动机)引擎,另一类称为NFA(非确定性有穷自动机)引擎,有时它们也被称为文本导向(Text-Directed)引擎和正则导向(Regex-Directed)引擎。

文本导向的引擎是一个以线性时间顺序执行的确定性有限自动机,因为它们不需要backtracking,也正是因为这样,它们也从不会连续两次地匹配相同字符。文本导向引擎会尽可能地匹配最长的字符串。但是由于确定性有限自动机只能包含唯一的有限状态,它就不可能利用逆向引用来匹配一个样式;文本导向引擎也不能显示地构建一个扩展(expansion),从而也就无法捕获子表达式。

文本导向的引擎的特性如下:

  • 查找迅速
  • 查找时间与字符串长度相关
  • 比非确定性有限自动机消耗更多内存
  • 编译正则表达式时,需要更多的时间

正则导向的引擎是一个非确定性有限自动机,这种算法将会测试所有可能的匹配情况,并且每次只接受第一个匹配的内容。因为非确定性有限自动机(NFA)能成功地为正则表达式构建一个特定的扩展,从而也就能捕获子表达式(捕获组)的匹配内容和逆向引用所指向的内容。并且,NFA可以进行回溯操作,这样的话它也就能精确地多次访问同样的状态,即使这个状态已经处于一个不同的路径,所以,在一个非常糟糕的情况下,它运行起来是很慢的。

在使用正则导向引擎时有一点是非常值得注意的,它总是返回最左侧的匹配内容,即使是后面的内容可能是更好的匹配内容;但这并不代表它永远地抛弃剩下的匹配内容,在适当的情况下,回溯操作可能会把其他匹配内容给筛选出来。当我们把构造好的正则表达式应用到一个字符串上时,引擎就会从第一个字符开始。它将按照表达式中的顺序,把所有可能的内容都尝试一次,但每次的结果只是正则导向引擎执行该次匹配操作所能返回的最左侧的匹配内容。

正则导向的引擎的特性如下:

  • 查找较慢
  • 查找时间与正则表达式相关
  • 比DFA占用的内存少(具体占用内存多少与构造的正则表达式相关)
  • 编译速度比DFA要快(具体编译时间与构造的正则表达式相关)
  • 使用回溯算法来尝试所有可能的匹配内容
  • 不同的回溯风格直接影响性能
  • 能够捕获子表达式
  • 支持逆向引用

三、正则表达式的适用范围

正则表达式能够帮助我们方便快捷的进行文字处理,校验数据的合法性,辅助程序开发 ,简化开发过程。而且,很多程序语言对正则表达式也都有着不同程度上的支持,这就是使得我们所掌握的正则表达式知识的应用面更为广泛。但是,一定要注意的是,可能会因为语言或工具的不同,对同样的正则表达式语法有着不同的解释,这就需要我们使用这些语法之前仔细查阅相关文档;不过也不用过于紧张,这样的情况可能是因特定的语言或工具对它所支持的正则表达式进行了扩展等行为造成的,但我们所掌握的绝大多数正则表达式知识都是通用的。

四、正则表达式工具介绍

在我们编写正则表达式样式时,如何知道编写出来的正则表达式能跟我们预想的匹配模式一致,或者是能够满足我们所要进行的操作呢?这就需要我们借助一些辅助性工具,最简单的也是最朴素的工具就是我们经常使用的一些文本编辑器,如EditPlus、UltraEdit和EmEditor等。当然,如果您的要求比较高的话,也可以使用一些专业的正则工具,如 Expresso、RegexBuddy 等。

Expresso 是一款用 .Net 技术编写正则表达式工具,我们可以从它的官方网站 www.ultrapico.com 免费下载。Expresso 非常适合作为正则表达式初学者的学习工具,同样,它也适合作为有经验的程序员或网页设计者的一个辅助性开发环境。要安装并使用 Expresso ,首先要保证的是我们的机器上已经安装了适合版本的 Mircosoft .Net Framework,该框架可以从微软网站免费获取,Windows SP2、Windows 2003 SP1 和 Vista 都已经集成了 .Net 框架,不需要我们另外安装。

首次启动 Expresso 时,Expresso 会为我们提高它所提供的示例正则表达式,如下图所示。从图中的选项卡来看,Expresso 为我们大致提供了字符串匹配、字符串替换、常用正在表达式类库、最近使用的正则表达式、正则表达式分析和正则表达式模式设定几个功能。当我们点击右边的按钮时,我们就能看到相应功能的运行结果,关于 Expresso 的详细用法我们会将在以后章节的示例中学到。

Expresso截图

目前流行的正则表达式工具种类有很多,如 Regex Coach、Regular Expression Designer等,并且还有一些提供正则表达式测试的网站,如 www.regextester.com 等,我们可以根据自己需求,选择合适的测试工具。

五、正则表达式不擅长的事情

正则表达式的主要作用的用于匹配某一种样式的字符或字符串,它本身并不具有逻辑校验功能。为什么要在这里提出这个话题呢,因为在国内一些大型的程序论坛中,经常有人问如何用正则表达式判断日期有效性这样含有复杂逻辑的问题。如果单纯地使用正则表达式验证日期的格式,如 YYYY/MM/DD 这样的形式,当然是很轻松就能做到的,但是,对于2月份不能出现31号这样的逻辑问题,用正则来实现有些勉为其难了,有些情况下甚至是无法实现或是实现了也是相当复杂的。

曾经看到一个验证日期有效性的正则表达式表达式:

(([0-9]{2}([02468][048])|([13579][26])))(02)(([0][1-9])|([1-2][0-9]))|(([0-9]{2}([02468][123579])|([13579][01345789])))(02)(([0][1-9])|([1][0-9])|([2][0-8]))|([0-9]{4})(([0](1|3|5|7|8))|10|12)(([0][1-9])|([1-2][0-9])|30|31)|([0-9]{4})(04|06|09|11)(([0][1-9])|([1-2][0-9])|30)

这样的写法如果是用在教学中,确实是一个不可多得的好例子,但要用在实际开发中,就不太合适了。首先,任何人看了这样长的一个正则表达式,心里想的第一个问题就是该如何看懂它——太复杂!其次,在编写它的时候,逻辑思路必须特别特别清晰,因为稍微一个不留神,就可能遗漏某个环节——难编写!第三,正则表达式在使用之前都是需要编译的,语法越复杂编译起来也就越慢,而且执行起来也不见得会比我们普通编写的程序代码跑得快——效率低!

所以,一定要记住,正则表达式的优势是进行样式匹配,而不是具体的逻辑处理。只有正确地认识到这一点,在程序编写时合理地使用正则表达式,才能明确问题的关键所在,得出一个最佳的解决方案。

六、关于正则表达式学习的几点建议

工欲善其事,必先利其器!所以,一个良好的正则学习工具是非常有必要的。这样不光能加快学习进程,还能有效地巩固我们学习过的知识。像我们在上面已经介绍过的 Expresso 这样正则表达式测试工具,对我们的学习都能起到很大的帮助作用。这些工具大多都能帮助我们创建、编辑正则表达式;并能对匹配的内容高亮显示、进行语法分析。另外,有的工具还附带常用的正则表达式校验类库、自动生成代码等功能。

在我们的学习过程中,最好是能把编写的正则表达式拿到程序代码里实际的跑一下,这会加深我们的理解。在很多程序语言中实现了字符串对正则的支持,如 Java 包 java.lang 中的 String 类就提供了 matches、replaceAll、replaceFirst、split 四个方法; 另外一种就是利用正则表达式类所提供的静态方法,如 .Net 命名空间 System.Text.RegularExpressions 中的 Regex 类就提供了 IsMatch、Replace 和 Split三个静态方法。总的来说,无论是字符串提供的普通方法,还是由正则表达式类所提供的静态方法,它们都是匹配、替换和分割三种操作。通过这样的学习方式,不光能够牢牢地掌握正则表达式语法,还能熟悉日常工作学习时所使用的常用正则表达式方法,一举两得,不用花费额外的时间来补习程序语言上的正则表达式知识了。

<!-- InstanceEndEditable -->
分享到:
评论

相关推荐

    简单入门正则表达式(侧重原理,附属实例)

    第一章 概述 第二章 正则表达式应用范围 ... 第六章 元字符与修饰符 ...共(十一章) 图文并茂,深入浅出

    PHP从入门到精通第二版

    第6章 正则表达式 第7章 PHP数组 第8章 PHP与Web页面交互 第9章 PHP与JavaScript交互 第10章 日期和时间 第2篇 核心技术 第11章 Cookie与Session 第12章 图形图像处理技术 第13章 文件系统 第14章 面向对象 第15章 ...

    JavaScript权威指南(第6版)(中文版).zip

    第一章为:JavaScript概述;第二章为:词法结构;第三章为:类型、值和变量;第四章为:表达式和运输符;第五章为:语句;第六章为:对象;第七章为:数组 第八章为:类和函数;第九章为:类和模块;第十章为:正则表达式的模式...

    Visual C# 2008从入门到精通.pdf

    第6章 字符串和正则表达式 第7章 结构化异常处理 第8章 委托与事件 第三篇 高级课题 第9章 Windows窗体 第10章 处理XML 第11章 文件和注册表操作 第12章 .NET数据访问 第13章 查的睦.NET数据 第14章 与SQL Server...

    PHP和MySQL WEB开发(第4版)

    第一篇 使用PHP 第1章 PHP快速入门教程 1.1 开始之前:了解PHP 1.2 创建一个示例应用:Bob汽车零部件商店 1.2.1 创建订单表单 1.2.2 表单处理 1.3 在HTML中嵌入PHP 1.3.1 使用PHP标记 1.3.2 PHP语句 1.3.3 空格 ...

    PHP和MySQL Web开发第4版pdf以及源码

    4.9 比较字符串函数和正则表达式函数 4.10 进一步学习 4.11 下一章 第5章 代码重用与函数编写 5.1 代码重用的好处 5.1.1 成本 5.1.2 可靠性 5.1.3 一致性 5.2 使用require()和include()函数 5.2.1 文件...

    PHP和MySQL Web开发第4版

    4.9 比较字符串函数和正则表达式函数 4.10 进一步学习 4.11 下一章 第5章 代码重用与函数编写 5.1 代码重用的好处 5.1.1 成本 5.1.2 可靠性 5.1.3 一致性 5.2 使用require()和include()函数 5.2.1 文件...

    用Python写网络爬虫PDF-理查德 劳森(Richard Lawson)

    2.2.1 正则表达式 26 2.2.2 Beautiful Soup 28 2.2.3 Lxml 30 2.2.4 性能对比 32 2.2.5 结论 35 2.2.6 为链接爬虫添加抓取回调 35 2.3 本章小结 38 第3章 下载缓存 39 3.1 为链接爬虫添加缓存支持 39 3.2 ...

    Python编程入门经典

    19.6.2 创建模型的第一步—— 配置数据库设置 379 19.7 创建模型:创建一个应用 程序 380 19.8 本章小结 382 19.9 习题 383 第20章 Web应用程序与Web 服务 385 20.1 REST:Web架构 386 20.1.1 REST的特性 386 20.1.2...

    2019千峰Python超详细入门教程(百度云盘分享).docx

    ├─千锋Python教程:第01章 第一个Python程序与数据存储及数据类型(9集) │ │ .DS_Store │ │ │ ├─code │ │ 1、数据存储.txt │ │ 2、第一个python程序.py │ │ 3、注释.py │ │ 4、输出与输入.py │ ...

    用Python写网络爬虫.pdf

    1.4 编写第一个网络爬虫 8 1.4.1 下载网页 9 1.4.2 网站地图爬虫 12 1.4.3 ID遍历爬虫 13 1.4.4 链接爬虫 15 1.5 本章小结 22 第2章 数据抓取 23 2.1 分析网页 23 2.2 三种网页抓取...

    ASPNET35开发大全第一章

    第一篇 .NET基础 第1章 认识ASP.NET 3.5 1.1 什么是ASP.NET 1.1.1 .NET历史与展望 1.1.2 ASP.NET与ASP 1.1.3 ASP.NET开发工具 1.1.4 ASP.NET客户端 1.1.5 ASP.NET 3.5新增控件 1.1.6 ASP.NET 3.5 AJAX 1.2 .NET应用...

    Java开发详解.zip

    031115_【第11章:Java常用类库】_正则表达式笔记.pdf 031116_【第11章:Java常用类库】_定时调度笔记.pdf 031201_【第12章:JAVA IO】_File类笔记.pdf 031202_【第12章:JAVA IO】_RandomAccessFile笔记.pdf 031203...

    21天学通JavaScript 源代码1(还有10章在源代码2文件)

    第一篇完整地讲解了JavaScript的基础知识,主要内容包括JavaScript概述、数据类型、常量与变量、表达式与运算符、程序语句、函数和数组等。第二篇专门介绍JavaScript中内置对象的应用,内容包括JavaScript对象基础、...

    21天学通JavaScript 源代码2(有一部分在源码1文件中)

    第一篇完整地讲解了JavaScript的基础知识,主要内容包括JavaScript概述、数据类型、常量与变量、表达式与运算符、程序语句、函数和数组等。第二篇专门介绍JavaScript中内置对象的应用,内容包括JavaScript对象基础、...

    shell 编程指南pdf

    第一部分 shell 第1章 文件安全与权限 1 1.1 文件 1 1.2 文件类型 2 1.3 权限 2 1.4 改变权限位 4 1.4.1 符号模式 4 1.4.2 chmod命令举例 5 1.4.3 绝对模式 5 1.4.4 chmod命令的其他例子 6 1.4.5 可以选择使用符号...

    Java2实用教程.rar

    5 8正则表达式 习题 第6章时间 日期和数字 6 1Date类 6 2Calendar类 6 3Math类 6 4BigInteger类 习题 第7章AWT组件及事件处理 7 1Java窗口 7 1 1 Frame常用方法 7 1 2菜单条 菜单 菜单项 7 1 3窗口与屏幕 7 2文本框 ...

    ASP.NET3.5从入门到精通

    第一篇 .NET基础 第 1 章认识 ASP.NET 3.5 1.1 什么是ASP.NET 1.1.1 .NET 历史与展望 1.1.2 ASP.NET 与ASP 1.1.3 ASP.NET 开发工具 1.1.4 ASP.NET 客户端 1.1.5 ASP.NET 3.5 新增控件 1.1.6 ASP.NET 3.5 AJAX 1.2 ...

    ActionScript开发技术大全

    14.1正则表达式概述 299 14.2正则表达式语法 300 14.2.1创建对象 300 14.2.2字符、元字符与元序列 301 14.2.3字符集 306 14.2.4组 307 14.3标记、属性与方法 310 14.3.1正则表达式的标记与属性 310 14.3.2正则表达式...

    redhat linux教材20课程学习文档

    第一章 概述 1.1 Linux 的历史及背景 1.1.1 什么是 Linux? 1.1.2 Linux 该怎么念? 1.1.3 Linux 的历史 1.1.4 Linux的优点 1.2 Linux与开源软件 1.3 Linux 与 Windows 的比较 1.3.1 开发模式和系统架构的区别 1.3.2 ...

Global site tag (gtag.js) - Google Analytics