前言 本书关注的是一种强大的工具——“正则表达式”。它将教会读者如何使用正则表达式解决各种问题,以及如何充分使用支持正则表达式的工具和语言。许多关于正则表达式的文档都没有介绍这种工具的能力,而本书的目的正是让读者“精通”正则表达式。.
许多种工具都支持正则表达式(文本编辑器、文字处理软件、系统工具、数据库引擎,等等),不过,要想充分挖掘正则表达式的能力,还是应当将它作为编辑语言的一部分。例如Java、JScript、Visual
Basic、VBScript、JavaScript、ECMAScript、C、C++、C#、elisp、Perl、Python、Tcl、Ruby、PHP、sed和awk。事实上,在一些用上述语言编写的程序中,正则表达式扮演了极其重要的角色。
正则表达式能够得到众多语言和工具的支持是有原因的:它们极其有用。从较低的层面上来说,正则表达式描述的是一串文本(a chunk
of
text)的特征。读者可以用它来验证用户输入的数据,或者也可以用它来检索大量的文本。从较高的层面上来说,正则表达式容许用户掌控他们自己的数据——控制这些数据,让他们为自己服务。掌握正则表达式,就是掌握自己的数据。
本书的价值 The Need for This Book
本书的第1版写于1996年,以满足当时存在的需求。那时还没有关于正则表达式的详尽文档,所以它的大部分能力还没有被发掘出来。正则表达式文档倒是存在,但它们都立足于“低层次视角”。我认为,那种情况就好像是教一些人英文字母,然后就指望他们会说话。
第2版与第1版间隔了五年半的时间,这期间,互联网迅速流行起来,正则表达式的形式也有了极大的扩张,这或许并不是巧合。几乎所有工具软件和程序语言支持的正则表达式也变得更加强大和易于使用。Perl、Python、Tcl、Java和Visual
Basic都提供了新的正则支持。新出现的支持内建正则表达式的语言,例如PHP、Ruby、C#,也已经发展壮大,流行开来。在这段时间里,本书的核心——如何真正理解正则表达式,以及如何使用正则表达式——仍然保持着它的重要性和参考价值。
不过,第1版已经逐渐脱离了时代,必须加以修订,才能适应新的语言和特性,也才能对应正则表达式在互联网世界中越来越重要的地位。第2
版出版于2002年,这一年的里程碑是java.util.regex、Microsoft .NET Framework和Perl
5.8的诞生。第2 版全面覆盖了这些内容。关于第2 版,我**的遗憾就是,它没有提及PHP。自第2 版诞生以来的4
年里,PHP的重要性一直在增加,所以,弥补这一缺憾是非常迫切的。
第3版在前面的章节中增加了PHP的相关内容,并专门为理解和应用PHP的正则表达式增加了一章全新的内容。另外,该版对Java的章节也进行了修订,做了可观的扩充,反映了Java1.5和Java1.6的新特性。
目标读者 Intended Audience
任何有机会使用正则表达式的人,都会对本书感兴趣。如果您还不了解正则表达式能提供的强大功能,这本书展示的全新世界将会让您受益匪浅。即使您认为自己已经是掌握正则表达式的高手了,这本书也能够深化您的认识。第1版面世后,我时常会收到读者的电子邮件反映说“读这本书之前,我以为自己了解正则表达式,但现在我才真正弄明白”。
以与文本打交道为工作(如Web开发)的程序员将会发现,这本书**称得上是座金矿,因为其中蕴藏了各种细节、暗示、讲解,以及能够立刻投入到实用中的知识。在其他任何地方都难以找到这样完整而详尽的资料。
正则表达式是一种思想——各种工具以各种方式(数目远远超过本书的列举)来实现它。如果读者理解了正则表达式的基本思想,掌握某种特殊的实现就是易如反掌的事情。本书关注的就是这种思想,所以其中的许多知识并不受例子中所用的工具软件和语言的束缚。
如何阅读 How to Read This Book
这本书既是教程,又是参考手册,还可以当故事看,这取决于读者的阅读方式。熟悉正则表达式的读者可能会觉得,这本书马上就能当作一本详细的参考手册,读者可以直接跳到自己需要的章节。不过,我并不鼓励这样做。
要想充分利用这本书,可以把前6
章作为故事来读。我发现,某些思维习惯和思维方式的确有助于完整的理解,不过*好还是从这几章的讲解中学习它们,而不是仅仅记住其中的几张列表。
故事是这样的,前6 章是后面4
章——包括Perl、Java、.NET和PHP——的基础。为了帮助读者理解每一部分,我交叉使用各章的知识,为了提供尽可能方便的索引,我投入了大量的精力(全书中有超过1
200处交叉引用,它们用符号加页码的形式标注)。
在读完整个故事以前,*好不要把本书作为参考手册。在开始阅读之前,读者可以参考其中的表格,例如第92页的图表,想象它代表了需要掌握的相关信息。但是,还有大量背景信息没有包含在图表中,而是隐藏在故事里。读者阅读完整个故事之后,会对这些问题有个清晰的概念,哪些能够记起来,哪些需要温习。
. 组织结构 Organization 全书共10章,可以从逻辑上粗略地分为三类,下面是略图: 导引
第1章:介绍正则表达式的基本概念。 第2章:考察利用正则表达式进行文本处理的过程。
第3章:提供对于特性和工具软件的概述以及简史。 细节 第4章:揭示了正则表达式的工作原理的细节。
第5章:利用第4章的知识,继续学习各种例子。 第6章:详细讨论效率问题。 特定工具的知识
第7章:详细讲解Perl的正则表达式。 第8章:讲解Sun提供的java.util.regex包。
第9章:讲解.NET的语言中立的正则表达式包。 第10章:讲解PHP中提供正则功能的preg套件
导引部分会把完全的门外汉变成“对问题有感觉”的新手。对正则表达式有一定经验的读者完全可以快速翻阅这些章节,不过,即使是对于相当有经验的读者来说,我仍然要特别**第3章。
第1章,正则表达式入门,是为完全的门外汉准备的。我以应用相当广泛的程序egrep为例,介绍正则表达式,我也提供了我的视角:如何“理解”正则表达式,来为后面章节所包括的**概念打下坚实的基础。即使是有经验的读者,浏览本章也会有所收获。
第2章,入门示例拓展,考查了支持正则表达式的程序设计语言的真实文本处理过程。附加的示例提供了后面章节详细讨论的基础,也展示了**正则表达式调校背后的重要思考过程。为了让读者学会“正则表达式的套路”,这章出现了一个复杂问题,并讲解了两种全然不相关的工具如何分别通过正则表达式来解决它。
第3章,正则表达式的特性和流派概览,提供了当前经常使用的工具的多种正则表达式的概览。因为历史的混乱,当前常用的正则表达式的类型可能差异巨大。此章同时介绍了正则表达式以及使用正则表达式的工具的历史和演化历程。本章末尾也提供了“**话题引导”。此引导是读者学习此后**内容的路线图。
细节.. The Details
了解了基础知识之后,读者需要弄明白“如何使用”及“这么做的原因”。就像“授人以渔”的典故一样,真正懂得正则表达式的读者,能够在任何时间、任何地点应用关于它的知识。
第4章,表达式的匹配原理,循序渐进地导入本书的核心。它从实践的角度出发,考察了正则引擎真实工作的重要的内在机制。懂得正则表达式如何处理工作细节,对读者掌握它们大有裨益。
第5章,正则表达式实用技巧,教育读者在高层次和实际的运用中应用知识。这一章会详细讲解常见(但复杂)的问题,目的在于拓展和深化读者对于正则表达式的认识。
第6章,打造**正则表达式,考察真实生活中大多数程序设计语言提供的正则表达式的**结果。本章运用第4章和第5章详细讲解的知识,来开发引擎的能力,并避免其中的缺陷。
特定工具的知识 Tool-Specific Information
学习完第4、5、6章的读者,不太需要知道特定的实现。不过,我还是用了4个整章来讲解4种流行的语言。
第7章,Perl,详细讲解了Perl的正则表达式,Perl大概是目前*流行的主要的正则表达式编程语言。在Perl中,与正则表达式相关的操作符只有四个,但它们组合出的选项和特殊情形带来了大量的程序选项——同时还有陷阱。对没有经验的开发人员来说,这种极其丰富的选项能够让他们迅速从概念转向程序,当然也可能是雷场。本章的详细介绍有助于给读者指出一条光明大道。
第8章Java,详细介绍了jav.util.regex包,从Java
1.4以后,它已经成为了Java语言的标准部分。本章主要关注的是Java 1.5,但也提及了它与Java 1.4.2和Java
1.6的差别。
第9章,.NET,是微软尚未提供的.NET正则表达式库的文档。无论使用VB.NET、C#、C++、Jscript、VBScript、ECMAScript还是使用.NET组件的其他语言,本章都提供了详细内容,让读者能够充分利用.NET的正则表达式。
第10章,PHP,简要介绍了PHP内嵌的多个正则引擎,并详细介绍了preg正则表达式套件(regex
engine)的类型和API,这些是由PCRE正则表达式库提供的。 体例说明 Typographical
Conventions
在进行(或者谈论)详细的和复杂的文本处理时,保持**性是很重要的。差一个空格字符,可能导致截然不同的结果,所以我会在本书中使用下面的惯例:
正则表达式以[this]的形式出现。两端的符号表示“里面有一个正则表达式”,而正则表达式文