Preface
本书关注的是一种强大的工具——“正则表达式”。它将教会读者如何使用正则表达式解决各种问题,以及如何充分使用支持正则表达式的工具和语言。许多关于正则表达式的文档都没有介绍这种工具的能力,而本书的目的正是让读者“精通”正则表达式。
许多种工具都支持正则表达式(文本编辑器、文字处理软件、系统工具、数据库引擎,等等),不过,要想充分挖掘正则表达式的能力,还是应当将它作为编程语言的一部分。例如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,详细介绍了java.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」的形式出现。两端的符号表示“里面有一个正则表达式”,而正则表达式文字(例如用来检索的表达式)以‘this’的形式出现。有时候,省略两端的符号和单引号也不会造成歧义,此时我会省略它们。同样,屏幕截图通常以原来的样子出现,而不会用到上面两种符号。
●在文字文本和表达式内部的省略号会被特别标出。例如,[…]表示一对方括号,之间的内容无关紧要,而[…]表示一对方括号,其中包含三个句点。
●如果没有明确数字,可能很难判断“a b”之间有多少空格,所以出现在正则表达式和文字文本中的空格以“·”表示。这样“a····b”就清楚多了。
●我使用可见的制表符,换行符和回车字符:
●有时候,我会使用下画线或有色背景高亮标注文字文本或正则表达式的一部分。下面这句话中,下画线的部分表示表达式真正匹配的部分:
Because 「cat」matches/'instead of the word/'cat/',we realize...
这个例子中,下画线的部分高亮标记了表达式中添加的字符:
To make this useful,we can wrap 「Subject|Date」 with parentheses,and append a colon and a space.This yields
●本书包含了大量的细节和例子,所以我设置了超过1 200 处的交叉引用,帮助读者理解。它们通常表示为“☞123”,意思是“请参阅第 123 页”。举个例子:“…的说明在表8-2中(☞367)”。
练习
Exercises
有时候我会问个问题,帮助读者理解正在讲解的概念,尤其是在前几章这种问题更多。它们并不是摆设,我希望读者在继续阅读之前认真想想。请记住我的话,不要忽略它们的重要意义,本书中这样的问题并不多。它们可以当作自我测试题:如果不是几句话就能说明白的问题,最好是在复习相关章节之后再继续阅读。
为了避免读者直接看到问题的答案,我使用了一点技巧:问题的答案都必须翻页才能看到。通常你必须翻过一页才能看到标着ϖ的答案。这样答案在你思考问题的时候没法直接看到,但又很容易获得。
链接、代码、勘误及联系方式
Links,Code,Errata,and Contacts
写第1 版时,我发现修改书本上的URL,保持与实际一致是件很费工夫的事情,所以,我没有在书后罗列一个URL附录,而是提供统一的地址:
http://regex.info
在这里你可以找到与正则表达式相关的链接,书中的所有代码,可检索的索引以及其他资源。本书也可能存在错误☺,所以我提供了勘误。
如果你找到书中的错误,或者仅仅是希望给我写几句话,请写邮件到:[email protected]。
我们已尽力核验本书所提供的信息,尽管如此,仍不能保证本书完全没有瑕疵,而网络世界的变化之快,也使得本书永不过时的保证成为不可能。如果读者发现本书内容上的错误,不管是赘字、错字、语意不清,甚至是技术错误,我们都竭诚虚心接受读者指教。如果您有任何问题,请按照以下的联系方式与我们联系。
奥莱理软件(北京)有限公司
北京市 海淀区 知春路49号 希格玛公寓B座809室
邮政编码:100080
网页:http://www.oreilly.com.cn
E-mail:[email protected]
与本书有关的在线信息如下所示。
http://www.oreilly.com/catalog/regex3/(原书)
http://www.oreilly.com.cn/book.php?bn=978-7-121-04684-1(中文版)