正则表达式经典实例(第2版)

978-7-115-36660-3
作者: 【美】Jan Goyvaerts Steven Levithan
译者: 郭耀迟骋
编辑: 杨海玲

图书目录:

详情

全书基于8种常用的编程语言,给出了140多个使用正则表达式的经典实例,以帮助读者使用正则表达式来处理数据和文本,旨在教会读者很多新的技巧以及如何避免语言特定的陷阱,读者可以通过本书提供的实例解决方案库来解决实践中的复杂问题。

图书摘要

版权信息

书名:正则表达式经典实例(第2版)

ISBN:978-7-115-36660-3

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。


著    [美] Jan Goyvaerts Steven Levithan

译    郭 耀 迟 骋

审  校 余 晟

责任编辑 杨海玲

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


Copyright©2012 by O’Reilly Media, Inc.

Simplified Chinese Edition, jointly published by O’Reilly Media, Inc. and Posts & Telecom Press, 2014. Authorized translation of the English edition, 2012 O’Reilly Media, Inc., the owner of all rights to publish and sell the same.

All rights reserved including the rights of reproduction in whole or in part in any form.

本书中文简体版由O’Reilly Media, Inc.授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式复制或抄袭。

版权所有,侵权必究。


本书讲解了基于C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等8种常用编程语言使用正则表达式的经典实例。书中提供了上百种可以在实战中使用的实例,帮助读者使用正则表达式来处理数据和文本。本书针对如何使用正则表达式来解决性能不佳、误报、漏报等常见的错误以及完成一些常见的任务,给出了基于C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等编程语言的解决方案,旨在教会读者很多技巧以及避免特定语言的陷阱的方法,读者可以通过本书提供的实例解决方案库来解决实践中的复杂问题。

本书适合对正则表达式感兴趣的软件开发人员和系统管理员阅读。


O’Reilly Media通过图书、杂志、在线服务、调查研究和会议等方式传播创新知识。自1978年开始,O’Reilly一直都是前沿发展的见证者和推动者。超级极客们正在开创着未来,而我们关注真正重要的技术趋势——通过放大那些“细微的信号”来刺激社会对新科技的应用。作为技术社区中活跃的参与者,O’Reilly的发展充满了对创新的倡导、创造和发扬光大。

O’Reilly为软件开发人员带来革命性的“动物书”;创建第一个商业网站(GNN);组织了影响深远的开放源代码峰会,以至于开源软件运动以此命名;创立了《Make》杂志,从而成为DIY革命的主要先锋;公司一如既往地通过多种形式缔结信息与人的纽带。O’Reilly的会议和峰会集聚了众多超级极客和高瞻远瞩的商业领袖,共同描绘出开创新产业的革命性思想。作为技术人士获取信息的选择,O’Reilly现在还将先锋专家的知识传递给普通的计算机用户。无论是通过书籍出版、在线服务或者面授课程,每一项O’Reilly的产品都反映了公司不可动摇的理念——信息是激发创新的力量。

“O’Reilly Radar博客有口皆碑。”

      ——Wired

“O’Reilly凭借一系列(真希望当初我也想到了)非凡想法建立了数百万美元的业务。”

      ——Business 2.0

“O’Reilly Conference是聚集关键思想领袖的绝对典范。”

      ——CRN

“一本O’Reilly的书就代表一个有用、有前途、需要学习的主题。”

      ——Irish Times

“Tim是位特立独行的商人,他不光放眼于最长远、最广阔的视野并且切实地按照Yogi Berra的建议去做了:‘如果你在路上遇到岔路口,走小路(岔路)。’回顾过去Tim似乎每一次都选择了小路,而且有几次都是一闪即逝的机会,尽管大路也不错。”

      ——Linux Journal


正则表达式在过去十多年间越来越普及。如今,所有常用的编程语言都会包含一个强大的正则表达式函数库,甚至在语言本身就内嵌了对于正则表达式的支持。许多开发人员都会利用这些正则表达式的功能,在应用程序中为用户提供使用正则表达式对其数据进行查找或者过滤的能力。正则表达式已经无处不在。

随着正则表达式的广泛采用,出现了许多相关的著作。其中大多数都很好地讲解了正则表达式的语法,并且还会提供一些例子以及参考实现。然而,我们还没有看到有任何一本书能够针对处理计算机和不同因特网应用上的文本所遇到的各种实际问题为读者提供基于正则表达式的解决方案。因此,本书作者Steve和Jan决定写一本书来满足这种需求。

我们特别希望能够展现给读者的是:如何使用正则表达式来解决那些正则表达式经验有限的人认为无法解决的问题,或者软件纯粹主义者认为不能用正则表达式来解决的问题。因为如今正则表达式已无处不在,所以它们通常可以作为便利的工具被最终用户直接使用,而不需要程序员团队的参与。即使是对程序员来说,常常也可以在信息检索和修改的任务中采用一些正则表达式来节省大量时间,因为这些功能如果使用过程式代码来实现,可能会需要几小时甚至几天的时间,也可能会由于需要采用第三方的函数库,而不得不经过事先审查和管理人员的审批。

与IT业界流行的东西一样,正则表达式也拥有许多种不同的实现,以及不同程度的兼容性。这就出现了许多不同的正则表达式流派(flavor),它们在处理一个特定正则表达式的时候并不总是拥有完全一样的表现,有时候甚至会无法正常工作。

在许多书中的确也提到了目前存在的不同流派,并且指出了其中的一些区别。但是,它们通常会选择在不同地方略掉一些流派——特别是当某种流派缺少特定功能的时候,而不是为之提供替代解决方案或者变通方法。而当需要在不同的应用程序或编程语言中使用不一样的正则表达式流派的时候,就会令人感到沮丧。

在文字方面,也常常可以看到一些不严格的表达,例如“所有人现在都在使用Perl风格的正则表达式”,但是这种说法轻视了大范围的不兼容。即使都是“Perl风格”的函数库也有显著的区别,而与此同时Perl也在持续不断地发展。过度简单化的印象可能会导致程序员浪费半小时的时间来运行调试器却得不到任何结果,而不是去认真检查他们的正则表达式的实现细节。甚至当他们发现所依赖的一些功能不存在的时候,都不知道该如何找到变通方法。

本书是市场上第一本面面俱到地讨论所有流行且强大的正则表达式流派的书,并且从头到尾贯穿全书。

如果你经常在计算机上处理文本,不管是搜索一大堆的文档,还是在文本编辑器中处理文本,抑或是开发需要搜索或处理文本的软件,都应该读一读这本书。正则表达式对于上述这些工作来说是一个非常优秀的工具。本书会教给你需要了解的关于正则表达式的所有东西。你不需要任何先前的经验,因为我们会从正则表达式最基本的概念讲起。

如果你已经拥有使用正则表达式的经验,会发现其他书籍和网上文章中经常一带而过的大量细节。如果你曾经遭遇过正则表达式在一个应用程序中可用而在另外一个程序中不可用的情形,就会因为本书给出了世界上最流行的7种正则表达式流派的翔实的讲解,而感到受益颇多。我们把整本书组织成一本经典实例,因此你可以直接跳到想要细细阅读的话题。如果你从头到尾阅读了整本书,就会成为一个正则表达式的世界级“大厨”。

无论你是否是程序员,本书都会教给你使用正则表达式所需知道的所有知识,并且还会讲解更多其他内容。如果你想要在文本编辑器、查找工具,或是任意带有“使用正则表达式”选项输入框的应用程序中使用正则表达式,你根本不需要任何编程经验就可以阅读本书。本书中的大多数例子都拥有完全基于一个或多个正则表达式的解决方案。

如果你是程序员,那么第3章会讲解在源代码中应用正则表达式所需的所有信息。这一章假设读者熟悉所选用的编程语言的基本语言特性,但是并不假设你在源代码中曾经使用过任何正则表达式。

.NET、Java、JavaScript、PCRE、Perl、Python以及Ruby,这些不只是一些用在封面上的热门词汇,它们是本书要讲到的7种正则表达式流派。我们把这7种流派等同对待,同时还会特别仔细地指出这些正则表达式流派中我们所能找到的所有不一致的地方。

关于编程的一章(第3章)中包含如下语言的代码示例:C#、Java、JavaScript、PHP、Perl、Python、Ruby以及VB.NET。同样,每一个实例都有这8种语言的解决方案和解释。虽然这样做会让这一章看起来有些啰唆,但是读者可以很轻松地跳过那些不感兴趣的语言的讨论,而不会错过所选用语言中应当知道的任何内容。

本书的前3章讲解一些实用的工具和基本信息作为读者使用正则表达式的基础。随后的每一章则介绍各种不同的正则表达式以对文本处理的某个领域进行深入讲解。

第1章讲解正则表达式的作用,并介绍了一系列工具,这些工具会使你学习、创建和调试正则表达式更加容易。

第2章介绍正则表达式的每个元素和特性,以及高效使用正则表达式的重要指导。这一章构成完整的正则表达式指南。

第3章详细介绍了编码相关的技术,并且包含了在本书中涉及的每种编程语言中使用正则表达式的代码示例。

第4章中包含如何处理常见用户输入的实例,如日期、电话号码以及不同国家的邮政编码。

第5章探讨常见的文本处理任务,例如检查文本行中是否包含特定的单词。

第6章会讲解如何检测整数、浮点数以及这些输入的几种其他格式。

第7章讲解分析源代码和其他文本文件的基础,并演示了如何使用正则表达式处理日志文件。

第8章展示如何能够把在因特网上和Windows系统中常用的这些字符串拆分开来,并且利用它们来查找信息。

第9章讲解如何处理HTML、XML、逗号分隔的数值(CSV),以及INI风格的配置文件。

本书在排版上采用如下约定。

等宽字体

表示程序清单。

等宽斜体

表示应该用用户所提供的值或根据上下文确定的值来替换的文本。

‹Regular●expression› (正则表达式)

用来表示一个正则表达式,它可以单独出现,也可以出现在向某个应用程序的查找框中输入正则表达式的时候。正则表达式中的空格会使用一个灰色圆点来表示以使它们更明显。使用“宽松排列”(free-spacing)模式时,则不使用圆点表示空格,因为该模式下会忽略空格。

«Replacement●text» (替代文本)

用来表示在“查找和替换”的操作中,正则表达式所匹配的文本会被替换成的文本。在替代文本中的空格也会用一个灰色圆点来表示。

Matched text(匹配文本)

用来表示与正则表达式相匹配的目标文本(subject text)中的一部分。

在正则表达式中的省略号用来说明在使用该正则表达式之前必须“把这里的空白填好”。相应的文字解释中会告诉你在其中应该填入什么样的内容。

CR、LF 和CRLF

CR、LF 和 CRLF放在黑框中用来表示在字符串中实际出现的换行字符,而不是正则表达式中的字符转义序列(character escapes),如\r、\n和\r\n。要创建这些字符,可以通过在应用程序的多行编辑控件中按回车键(Enter),或者也可以通过在源代码中使用多行字符常量,比如C#中的逐字字符串(verbatim string),或是Python语言中的三引号字符串(triple-quoted string)。

这个符号表示回车箭头,它与键盘上的回车(Return或Enter)键上的符号一样,用来表示必须打断才能使之符合印刷页面的宽度。当你在源代码中键入这些代码的时候,不需要按回车键,而是应该把所有内容都键入同一行之中。

 

 

这个图标表示提示、建议或者一般的注记。

 

 

 

这个图标用来说明警告或注意事项。

 

本书的目的就是要帮助读者完成手头的工作。一般来说,读者可以随意在程序和文档中使用本书中出现的代码。除非你打算复用本书中大量的代码,否则并不需要联系我们以获得许可。销售或者发布O’Reilly图书中包含示例的CD-ROM则必须要获得许可。引用本书或者引用其中的示例代码来回答问题并不需要获得许可。在你的产品文档中利用本书中的大量代码示例则需要获得许可。

如果读者在引用本书时提供出处,我们会很感激,虽然我们并不要求你一定这样做。提供出处的时候通常需要包括书名、作者、出版社和书号(ISBN)。例如:“Regular Expressions Cookbook by Jan Goyvaerts and Steven Levithan. Copyright 2012 Jan Goyvaerts and Steven Levithan, 978-1-449-31943-4.”。

如果你觉得对代码示例的使用可能会超出上面所给出的许可范围,或是属于合理使用的范围之外,那么请随时通过permissions@oreilly.com联系我们。

如果你想就本书发表评论或有任何疑问,敬请联系出版社。

美国:

O’Reilly Media Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472

中国:

北京市西城区西直门南大街2号成铭大厦C座807室(100035)
奥莱利技术咨询(北京)有限公司

我们还为本书建立了一个网页,其中包含了勘误表、示例和其他额外的信息。你可以通过如下地址访问该网页:

http://oreilly.com/catalog/978144319434

关于本书的技术性问题或建议,请发邮件到:

bookquestions@oreilly.com

欢迎登录我们的网站(http://www.oreilly.com),查看更多我们的书籍、课程、会议和最新动态等信息。

我们的其他联系方式如下:
Facebook: http://facebook.com/oreilly
Twitter: http://twitter.com/oreillymedia
YouTube: http://www.youtube.com/oreillymedia

我们要感谢O’Reilly Media, Inc.的编辑Andy Oram,他从头到尾给我们提供了莫大的帮助。我们还要感谢Jeffrey Friedl、Zak Greant、Nikolaj Lindberg和Ian Morse仔细地审阅了本书第1版技术内容,并感谢Nikolaj Lindberg、Judith Myerson和and Zak Greant审阅了本书第2版,他们提供的审阅意见使本书得以做到全面而且准确。


在你打开这本书的时候,很可能已经热切地期望,要在代码中插入本书中找到的那些包含诸多括号和问号的古怪字符串了。如果你已经准备好要“即查即用”,我们非常欢迎,第4~9章中会列出并讲解了各种实用的正则表达式。

但是如果阅读本书的前几章,你将为未来节省大量的时间。例如,本章会向读者介绍许多工具——其中一些工具是本书作者之一的Jan所开发的,这些工具可以帮你事先测试和调试正则表达式,而不用等到把它们塞到代码中之后再处理,那时候查找错误就非常困难了。而且开始这几章还会展示使用正则表达式的不同特性和选项,帮助你轻松应对遇到的问题,并帮助你理解正则表达式,从而提高它们的性能,以及学习不同语言——甚至是你最喜欢的编程语言的不同版本之间——在处理正则表达式的时候出现的细微差别。

因此,我们在这些背景知识上花费了大量的精力,相信读者在开始动手之前会阅读这些内容,或是在使用正则表达式时遇到挫折,而想要巩固你的理解的时候,会回头来阅读它们。

在本书的上下文中,正则表达式(regular expression)是一种可以在许多现代应用程序和编程语言中使用的特殊形式的文本模式。它们可以用来验证输入是否符合给定的文本模式;在一大段文本中查找匹配该模式的文本;用其他文本来替换匹配该模式的文本或者重新组织匹配文本的片段;把一块文本切分成一系列更小的文本,当然如果使用不当也可能搬起石头砸自己的脚。本书会帮助你确切理解正在做的事情,从而避免可能会造成的灾难性后果。

学会了使用正则表达式的技巧,就可以简化许多编程和文本处理的任务,并且让许多没有正则表达式则根本无法实现的任务成为可能。从一个文档中提取所有的电子邮件地址,至少需要几十行,甚至是几百行过程式代码——这些代码编写起来费事,维护起来也麻烦。但是,如果采用了合适的正则表达式,如在实例4.1中所给的那样,就只需要很少的几行甚至只要一行代码就可以了。


术语“正则表达式”的历史

术语“正则表达式”来源于数学与计算机科学理论,它用来反映被称为“正则性”的数学表达式特点。这样一个表达式可以通过一个确定性有限自动机(DFA)用软件来实现。一个DFA是一个不使用回溯的有限状态机。

最早版本的grep工具所使用的文本模式是数学意义上的正则表达式。尽管名字看起来是一样的,然而如今流行的Perl风格的正则表达式已经完全不是数学意义上的正则表达式了。它们是采用非确定性的有限自动机(NFA)来实现的。你稍后就会学到和回溯有关的所有内容。关于这条说明,实干的程序员需要记住的所有内容就是:象牙塔里的一些计算机科学家,很不喜欢自己精心定义的术语被套用到现实世界中更为有用的技术。


但是,如果你试图用一个正则表达式来做太多的事情,或者是在根本不适合的情形中非要使用正则表达式,就会明白为什么会存在如下的说法[1]

有些人每遇到一个问题,就会想“我知道怎么做,用正则表达式就可以了。”于是他们就有两个(而不是一个)问题需要解决了。

这些人所遇到的新问题指的就是他们并不会去阅读用户手册,也就是现在你手里的这本书。所以请继续读下去。正则表达式是一个强大的工具。如果你的工作涉及在计算机上编辑或是提取文本,牢固地掌握正则表达式就会为你少度过很多个不眠之夜。

上一小节的标题确实表述得不那么确切,我们并没有定义正则表达式到底是什么。我们也不可能给出定义。对于哪些文本模式是正则表达式,而哪些不是,并不存在正式的标准来给出严格精确的定义。可以想象得到,每种编程语言的设计人员,以及每款文本处理程序的开发人员,对于正则表达式应该是什么样子,都会有自己不同的想法。因此,我们就不得不面对这样一大堆不同的正则表达式流派。

幸运的是,绝大多数设计人员与开发人员都比较懒惰。如果可以照搬别人已经做好的工作,为什么非要自己创建一些全新的东西呢?正因为此,所有现代的正则表达式流派,包含本书要讨论的这些流派,其历史都可以追溯到Perl编程语言。我们把这些流派都称作Perl风格的正则表达式。它们的正则表达式语法都非常相似,而且在大多数情况下是相互兼容的,但也不是完全如此。

作家也都很懒。在本书中,我们通常会使用regex或regexp来指代一个单个的正则表达式,而使用regexes来指代其复数形式[2]

正则流派并不是和编程语言一一对应的。脚本语言倾向于拥有它们自己内置正则表达式流派,其他语言则会依赖于函数库来提供正则表达式支持。有些函数库是对多种语言可用的,而某些特定的语言则会选用一些不同的函数库。

本章要讲解的内容只与正则表达式的流派有关,因此会彻底忽略任何与编程有关的考虑事项。从第3章开始,我们会给出一些代码片段,所以你可以先跳到第3章的第一节,以了解你将会使用哪些流派。但是现在请先忽略所有与编程相关的内容。下面一小节中列出的工具将会通过“动手学习”的方式,让你更方便地探索正则表达式的语法。

在本书中,我们选择了如今最为流行的正则流派。这些都是Perl风格的正则流派。有些流派会比其他流派多一些特性。但是如果两种流派拥有同一个特性的话,那么它们通常都会使用相同的语法。当然也会有例外,当我们遇到这些烦人的不一致情况时,在书中会加以提示。

所有这些正则流派都属于目前正在活跃开发中的编程语言和函数库的一部分。下面的流派列表会告诉你本书所用到的是哪些版本。在本书后面,如果所讲解的正则表达式在所有流派中效果都一样,那么我们在提到该流派时就不会区分其版本。绝大多数场合都是这种情况。除了会影响到一些边界情况的bug修复之外,正则表达式流派一般都不会改变,唯一例外是添加新的特性,原来认为是错误的语法,现在会被赋予新的含义。

.NET

微软公司的.NET框架通过System.Text.RegularExpressions包,提供了一个功能全面的Perl风格正则流派。本书涵盖了.NET 1.0~4.0版。而严格来讲,.NET正则流派只存在两个版本:1.0和2.0版。在 .NET 1.1、3.0和3.5版本中,并没有对正则类进行任何修改。.NET 4.0的正则类有一些新方法,但没有改变正则语法。

任何.NET编程语言,包括C#、VB.NET、Delphi for .NET,甚至包括COBOL.NET,都可以完整使用.NET正则流派。如果一个使用.NET开发的程序提供了正则表达式支持,即使它号称使用的是“Perl正则表达式”,你也可以非常确定它使用的就是.NET正则流派。很长时间里,令人大跌眼镜的一个例外则是Visual Studio(VS)自身。直到Visual Studio 2010,VS集成开发环境(IDE)中依然使用的是它从一开始就在用的一个老版本的正则流派,而这个实现根本就不是Perl风格的。本书写作时正处于测试版的Visual Studio 11[3],最终也在IDE中使用了.NET正则流派。

Java

Java 4是通过java.util.regex包提供内置正则表达式支持的第一个Java版本。这个包很快就超越了各种第三方Java正则库。除了它是标准的和内置的之外,它还支持了功能完整的Perl风格正则流派,其卓越的性能甚至可以媲美使用C语言编写的正则程序。本书会讲解Java 4、5、6和Java 7中的java.util.regex包。如果你在过去几年中用过Java语言开发的软件的话,那么其支持的正则表达式很可能是Java流派。

Java Script

在本书中,我们使用JavaScript这个术语指代在ECMA-262标准的第3版和第5版中定义的正则表达式流派。这个标准定义了ECMAScript编程语言,而这个语言更广为人知的是它在不同网页浏览器中的JavaScript与JScript实现。Internet Explorer(自5.5版)、Firefox、Opera与Safari都实现了ECMA-262的第3版或第5版。尽管在正则表达式功能方面,JavaScript 3与JavaScript 5的区别很小。然而,所有的浏览器都拥有各种与标准不同的边界情形bug。我们会在必要的地方指出这些问题。

如果一个网站允许使用正则表达式进行查找或者过滤,并且不用等待网站服务器的响应,那么它使用的就是JavaScript正则流派,这是唯一的跨浏览器客户端正则流派。即使是微软的VBScript与Adobe公司的ActionScript 3使用的也是它,不过ActionScript 3添加了一些额外特性。

XReg Exp

XRegExp是Steven Levithan开发的开源JavaScript库,可以从http://xregexp.com下载它。XRegExp扩展了JavaScript的正则表达式语法,并且消除了一些Web浏览器间的不一致。本书中的实例在用到标准JavaScript不支持的正则表达式特性时,会附加使用XRegExp的解决方案。如果一个解决方案的正则流派中列出了XRegExp,就意味着这个解决方案在JavaScript代码中使用XRegExp库时可以正常工作,而不使用XRegExp的标准JavaScript代码无法正常工作。如果一个解决方案的正则流派中列出了JavaScript,则意味着无论JavaScript代码中是否使用XRegExp,都可以正常工作。

本书涵盖了XRegExp 2.0版。所有实例都假设读者使用的是包含全部XRegExp Unicode特性的xregexp-all.js。

PCRE

PCRE是由Philip Hazel开发的“与Perl兼容的正则表达式” (Perl-Compatible Regular Expressions)的C语言函数库。这个开源代码库可以从http://www.pcre.org下载。本书涉及的PCRE版本包括第4版到第8版。

虽然PCRE号称是与Perl兼容的,而且与本书中的其他流派相比,它也是与Perl兼容性最好的,但是实际上它也只能称为是“Perl风格”的正则流派。有些特性,比如Unicode支持,会与Perl稍微有些不同,并且不能像在Perl中所允许的那样,把Perl代码混合到你的正则表达式之中。

因为它采用了开源许可,并且拥有稳定可靠的实现,所以PCRE被应用到了许多编程语言和程序中。它被内置到PHP中,并且被包装到了许多个Delphi的组件中。如果一个应用程序号称它支持“与Perl兼容”的正则表达式,而却没有具体列出它实际使用的正则流派,那么就很可能是PCRE。

Perl

Perl对于正则表达式的内置支持是正则表达式今天得以流行的主要原因。本书会涉及Perl 5.6、5.8、5.10、5.12和5.14版。上述每个版本都为Perl正则表达式语法添加了新的特性。当本书中标明某正则式在特定Perl版本中工作时,那该正则式可在该特定版本及本书所涉及的所有更新版本中正常工作。

许多应用程序和正则库都号称它们使用的是Perl或者与Perl兼容的正则表达式,而事实上它们仅仅是使用了Perl风格的正则表达式。它们使用与Perl相似的正则语法,但是所支持正则特性集并不重叠。最有可能的情形是,它们使用的是这一特性集中的正则表达式流派之一,而这些流派都是属于Perl风格的。

Python

Python通过它的re模块来支持正则表达式。本书会讲到Python 2.4至3.2版。Python 2.4、2.5、2.6和2.7版间的区别非常小。Python 3.0增强了Python处理正则表达式中Unicode的能力。Python 3.1和3.2则没有与正则相关的改进。

Ruby

与Perl语言类似,Ruby的正则表达式支持是Ruby语言自身的一部分。本书会涉及Ruby 1.8和Ruby 1.9。Ruby 1.8的默认编译会使用由Ruby源代码直接提供的正则表达式流派。而Ruby 1.9的默认编译则会使用Oniguruma正则表达式库。Ruby 1.8也可以编译使用Oniguruma,而Ruby 1.9也可以编译使用旧版本的Ruby正则流派。在本书中,我们会把原生Ruby流派称为Ruby 1.8,而把Oniguruma流派称为Ruby 1.9。

如果想测试一下你的站点使用的是哪个Ruby正则流派,可以尝试用一下正则表达式‹a++›。Ruby 1.8会说这个正则表达式是非法的,因为它并不支持占有量词(possessive quantifier),而它在Ruby 1.9中则会匹配一个或者多个字符a组成的字符串。

Oniguruma库设计为与Ruby 1.8向后兼容,它只是在其上添加了新的功能,而不会破坏已有的正则表达式。该实现甚至原样保留了大家认为应该修改的功能,例如:它依然使用‹ (?m) ›表示“点号匹配换行符”,即使其他正则表达式流派使用的都是‹ (?s) ›。

查找和替换(search-and-replace)对正则表达式来说是一个常见的任务。查找和替换的功能会接受一个目标字符串、一个正则表达式和一个替代字符串作为输入。它的输出则是把目标字符串中所有与正则表达式相匹配的字符串都替换为“替代文本”。

虽然替代文本(replacement text)并不是一个正则表达式,读者也可以使用某些特殊的语法构造动态的替代文本。所有的流派都允许把正则表达式或者某个捕获分组匹配到的文本,重新添加到替代字符串中。实例2.20和实例2.21会对此加以讲解。有些流派还会支持把匹配的上下文添加到替代文本中,这会在实例2.22中讲解。在第3章中,实例3.16将教你如何在代码中为每个匹配都生成不同的替代文本。

由于不同正则表达式软件开发人员的想法各异,所以出现了非常多的正则表达式流派,每种流派都拥有不同的语法和特性集。而这对于替代文本来说也是一样的。事实上,替代文本拥有比正则表达式更多的流派。构造一个正则表达式引擎是非常困难的。大多数程序员都倾向于复用某个已有的引擎,因为在已有的正则表达式引擎上绑定查找和替换的功能是相当容易的。这样做造成的结果是,如果正则表达式库没有内置查找和替换功能,它们之上就会存在许多替代文本的流派。

幸运的是,除了PCRE,本书中所有的正则表达式流派都拥有相对应的替代文本流派。PCRE中的这个问题却使得使用基于其流派正则程序的程序员感到无所适从。开源PCRE库中并不包含任何替换功能。结果是,所有基于PCRE的应用程序和编程语言都需要提供它们自己的查找和替换功能。大多数程序员都会试图去复制已有的语法,但是从来不会按照完全相同的方式去做。

本书会讲到如下的替代文本流派。关于同这些替代文本流派相对应的正则表达式流派,请参考1.1.1节。

.NET

System.Text.RegularExpressions包中提供了各种不同的查找和替换功能。.NET替代文本流派对应.NET的正则表达式流派。所有的.NET版本都使用相同的替代文本流派。.NET 2.0中新的正则表达式功能并不会影响替代文本的语法。

Java

java.util.regex包中包含了内置的查找和替换功能。本书会涉及Java 4、5、6和7。

JavaScript

在本书中,我们使用JavaScript这个术语指代在ECMA-262标准的第3版和第5版中所定义的替代文本流派与正则表达式流派。

XRegExp

Steven Levithan的XRegExp使用自带的replace()函数来消除各网页浏览器间的不一致,并支持XRegExp命名捕获分组的反向引用。本书使用命名捕获的实例的附加解决方案使用XRegExp。如果一个解决方案的替代文本流派中列出了XRegExp,就意味着在JavaScript代码中使用XRegExp库时可以正常工作,而不使用XRegExp的标准JavaScript代码无法正常工作。如果一个解决方案的替代文本流派中列出了JavaScript,则意味着JavaScript代码中是否使用XRegExp都可以正常工作。

本书涵盖了XRegExp 2.0版,可以从http://xregexp.com下载。

PHP

在本书中,PHP替代文本流派指的是PHP中的preg_replace函数。此函数使用了PCRE的正则表达式流派与PHP的替代文本流派,由PHP 4.0.0引入。

其他使用PCRE的编程语言并没有使用与PHP相同的替代文本流派。根据所使用的编程语言的设计者是从哪里得到的灵感,其中替代文本的语法可能会与PHP近似,或者也可能与本书中任何一种其他替代文本流派相似。

PHP还拥有一个ereg_replace函数。此函数使用一种不同的正则表达式流派(POSIX ERE),以及一种不同的替代文本流派。PHP官方已经建议弃用ereg函数,所以它不在本书讨论的范围之内。

Perl

Perl使用s/regex/replace/ 操作符提供内置的正则表达式替换支持。Perl的替代文本流派是与Perl的正则表达式流派相对应的。本书会涵盖Perl 5.6至Perl 5.14。Perl 5.10在替代文本中添加了命名向后引用(named backreference)支持,并在正则表达式语法中添加了命名捕获(named capture)支持。

Python

Python中的re模块提供了一个sub函数用于查找和替换。Python的替代文本流派对应于Python正则表达式流派。本书将涵盖Python 2.4至3.2。Python这些版本中的替代文本语法没有区别。

Ruby

Ruby的正则表达式支持是Ruby语言自身的一部分,包括其查找和替换函数。本书涵盖了Ruby 1.8和Ruby 1.9。虽然两个版本间正则式语法有很大不同,但Ruby 1.8和Ruby 1.9中的替代文本语法是基本一致的, Ruby 1.9仅在替代文本中添加了命名向后引用的支持。命名捕获也是Ruby 1.9的正则表达式中的一个新特性。

除非已经拥有了相当长的使用正则表达式编程的经验,否则建议你先在一个工具中试验一下正则表达式,而不是直接在源代码中使用它们。本章和第2章中提供的正则表达式示例都是原始正则表达式,其中并不包含编程语言(即使是Unlx shell)所必需的额外的转义符号。因此可以直接把这些正则表达式输入到一个应用程序的查找框中。

第3章讲解如何把正则表达式整合到源代码中。把一个字面的(literal)正则表达式作为一个字符串引用,会让它更加难懂,因为字符串的转义规则会与正则表达式的转义规则混杂在一起。我们在实例3.1才会开始讲解这些内容。一旦理解了正则表达式的基本知识,你就能够从无数的反斜杠的背后看到“森林”。

本节要介绍的工具同样会提供调试和语法检查的功能,以及在绝大多数编程环境中并不会获得的其他反馈信息。因此,在开发应用程序时研究正则表达式的时候,你可能会发现在把一个复杂的正则表达式插入到程序中之前,首先使用这类工具试验一下可能会非常有用。

在本书写作之时,RegexBuddy(如图1-1所示)是用来创建、测试和实现正则表达式功能最为丰富的工具。它拥有独特的能力,可以仿真本书中讲到的所有正则表达式的流派,甚至可以在不同的流派之间进行转换。

图1-1 RegexBuddy

RegexBuddy是由本书作者之一Jan Goyvaerts设计和开发的。设计和开发RegexBuddy使Jan成为了正则表达式的专家;由于使用了RegexBuddy,本书的另一位作者Steven迷恋上了正则表达式,最终向O’Reilly出版社建议出版这本书。

如果觉得屏幕截图(如图1-1所示)看起来比较繁杂,那是因为我们特意并排列出了大多数的面板,用来展示RegexBuddy的强大功能。实际上默认的视图会把所有的面板都很简洁地压缩成一行标签。另外,你还可以选择把一些面板拖动到另外一台显示器上。

要想尝试本书中给出的某个正则表达式,只需要把它键入RegexBuddy窗口上端的编辑框中。RegexBuddy会自动对正则表达式应用语法着色,从而使错误和括号不匹配的情形更容易看清楚。

在键入正则表达式的同时,Create面板会自动构造一个用英语描述的详细分析。在该正则表达式的树中双击任意的描述,可以编辑正则表达式的对应部分。你还可以手动向正则表达式中添加新的部分,或者通过单击Insert Token按钮从菜单中选择想要的操作。例如,如果不记得肯定型顺序环视(positive lookahead)的复杂语法,可以依靠RegexBuddy来帮助添加正确的字符。

在Test面板上可以键入或者粘贴一些示例文本。当Highlight按钮激活的时候,RegexBuddy会自动高亮显示与正则表达式匹配的文本。

最经常会用到的一些按钮如下。

List All

显示所有匹配的列表。

Replace

顶端的Replace按钮会显示一个新的窗口,使你可以输入替代文本。在Test框中的Replace按钮则能够查看在完成替换之后的目标文本。

Split(Test面板上的按钮,而不是顶端的按钮)

把你给的正则表达式当做是一个分隔符号,使用这个正则表达式,根据在目标文本中找到的匹配把目标文本拆分成多个记号(token)。

单击上述任意一个按钮,并选择Update Automatically(自动更新),就可以让RegexBuddy在编辑正则表达式或者目标文本的时候,同步显示动态结果。

要想看到正则表达式到底会(或者不会)如何执行,在Test面板上单击一个高亮显示的匹配或者是正则表达式没有能够产生匹配的地方,然后单击Debug按钮。RegexBuddy会转到Debug面板上,逐步展示整个匹配的过程。单击调试器输出的任意地方,就可以查看哪些正则表达式记号匹配了你所单击的文本。单击正则表达式则可以在调试器中高亮显示正则表达式的该部分。

在Use面板上,选择你最喜欢的编程语言。然后,选择一个功能就可以立即生成实现该正则表达式的源代码。RegexBuddy的源代码模板可以使用内置的模板编辑器进行完整编辑。你还可以添加新的功能甚至是新的语言,或者是修改内置的模板。

如果想在一个更大的数据集上测试正则表达式,转到GREP面板上就可以在任意数量的文件和文件夹上进行查找(以及替换)。

当你在维护的源代码中发现一个正则表达式的时候,可以把它复制到剪贴板上,包括其中用于分隔的引号和斜杠。在RegexBuddy中,单击顶端的Paste按钮,并选择你的编程语言字符串风格。该正则表达式就会以原始正则表达式的形式出现在RegexBuddy中,而字符串字面量(string literal)必需的额外引号和转义符号都被去掉了。使用顶部的Copy按钮就可以创建一个按照你所要求的语法的字符串,然后可以把它重新粘贴回源代码中。

经验增长以后,用户就可以在Library面板上构建起一个便于使用的正则表达式库。在保存正则表达式的时候,别忘了添加对应的详细的描述与测试对象。即使是对专家来说,正则表达式也可能会是难以捉摸的。

如果确实无法搞明白一个正则表达式是怎么回事,可以单击Forum面板,然后单击Login按钮。如果已经购买了RegexBuddy,就会出现登录屏幕。单击OK,就会立即连接到RegexBuddy用户论坛中。Steven和Jan经常会出现在这个论坛回答用户的问题。

RegexBuddy可以运行在Windows 98/ME/2000/XP/Vista/7/8上。对于Linux和Apple爱好者,RegexBuddy同样可以运行在VMware、Parallels、CrossOver Office之上,另外它在WINE上也可以运行,但是可能会存在一些问题。可以从www.regexbuddy.com/ RegexBuddyCookbook.exe下载到RegexBuddy的免费评估的版本。除了用户论坛之外,该试用版包含了可以使用7天的完整功能。

RegexPal(如图1-2所示)是由本书的作者之一Steven Levithan所创建的在线正则表达式测试工具。你所需要的仅仅是一个版本较新的网页浏览器。RegexPal全部是由JavaScript编写的。因此,它只支持JavaScript正则流派,这与你用来访问它的网页浏览器中所实现的正则表达式一样。

图1-2 RegexPal

如果想尝试一下本书中列出的某个正则表达式,只需访问http://www.regexpal.com。在最上方的输入框中键入正则表达式。RegexPal会自动对正则表达式应用语法着色,从而可以立即显示这个正则表达式是否存在任何语法错误。RegexPal知晓处理JavaScript正则表达式时的浏览器间兼容性问题,而这些问题可能会毁掉你的一整天。如果某个特定的语法在某些浏览器中不能正常工作的话,那么RegexPal会把它高亮显示为错误。

现在,你可以在中间的大输入框中键入或者粘贴一段样本文本。RegexPal会自动高亮与正则表达式匹配的文本。

在这个工具中并不需要单击任何按钮,因此RegexPal是最为方便的在线正则表达式测试工具之一。

RegexMagic(如图1-3所示)是另一款由Jan Goyvaerts设计和开发的工具软件。RegexBuddy的目标是可以更为容易地处理正则表达式语法,而RegexMagic则主要设计给那些不愿意接触正则表达式语法,更不肯读500页正则表达式图书的人。

图1-3 RegexMagic

在RegexMagic中,可以基于样本文本和RegexMagic的高级别模式描述想要匹配的文本。屏幕截图中演示了只需选择“Email address”(电子邮件地址)模式,即可得到一个匹配电子邮件地址的正则表达式。你也可以自定义模式以限制允许的用户名和主机域名,并且可以选择是否允许或必需mailto:前缀。

既然选择了读这本书,那你已经身处精通正则表达式的道路上。RegexMagic不应成为你使用正则式的主要工具,但在一些情况下它仍然十分便利。在实例6.7中我们讲解了该如何创建一个正则表达式来匹配一个范围内的数值字符串。尽管用正则表达式来判断一个数值字符串是否在某个范围内并不是最好的方法,但有时只能使用正则表达式来解决问题。内置正则引擎的应用程序远比内置脚本语言的多得多。虽然实例6.7中描述的技术没有什么难度,但手动完成这项工作还是十分枯燥乏味。

试想一下,如果要匹配的十进制数字位于2 147 483 648(231)到4 294 967 295(232–1)的范围内,而不是实例6.7中那些简单的示例。在RegexMagic中,只需选择“Integer”(整数)模式,选择“decimal”(十进制)选项,并将范围限制在2147483648..4294967295。在“strict”(严格)模式下,RegexMagic会立即生成如下“望而生畏的正则式”:

\b(?:429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6]↵
[0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8]↵
[0-9]{7}|4[01][0-9]{8}|3[0-9]{9}|2[2-9][0-9]{8}|21[5-9][0-9]{7}|214[89]↵
[0-9]{6}|2147[5-9][0-9]{5}|214749[0-9]{4}|214748[4-9][0-9]{3}|2147483↵
[7-9][0-9]{2}|21474836[5-9][0-9]|214748364[89])\b
  正则选项:正则流派:.NET、Java、JavaScript、PCRE、Perl、Python、Ruby

RegexMagic可以运行在Windows 98/ME/2000/XP/Vista/7/8上。对于钟爱Linux和Apple的用户,RegexMagic同样可以运行在VMware、Parallels、CrossOver Office之上,另外它也可以在WINE上运行,不过可能会存在一些问题。可以从http://www.regexmagic. com/RegexMagicCookbook.exe下载到RegexMagic的免费评估版本。除了用户论坛之外,该试用版包含了可以使用7天的完整功能。

创建一个简单的正则表达式在线测试工具并不困难。如果你拥有一些基本的Web开发技能,那么只需要第3章中的信息就足以构建自己的正则表达式工具了。成百上千的人已经这样做过,其中有些人还添加了一些额外的功能,值得加以介绍。

1.RegexPlanet

RegexPlanet(http://www.regexplanet.com/)是由Andrew Marcuse开发的网站。它出名的原因是它允许用户在很多种正则库中测试正则式,比我们知道的任何一个网站都要多。在首页上可以找到这些语言的测试工具链接,包括Java、JavaScript、.NET、Perl、PHP、Python和Ruby。它们都使用相同的基本界面。只有选项列表依据各编程语言而定。图1-4演示的是.NET版本。

在“regular expression”文本框键入或粘贴正则表达式。如果想要测试“查找和替换”,在“replacement”文本框中粘贴替代文本。你可以在任意数量的不同目标字符串上测试正则表达式,将目标字符串粘贴到各“input”文本框中即可。如果需要5个以上文本框,单击“more inputs”。虽然“regex”和“input”文本框只会显示一行,但是可以键入或粘贴多行文本。滚动箭头显示在文本框右侧。

输入完后,点击“test”按钮将所有字符串发送到regexplanet.com服务器。结果页面(如图1-4所示)会在顶部列出所有测试结果。前两行显示你的输入,余下各行显示不同函数的执行结果。站点支持的各编程语言的结果格式各不相同。

2.regex.larsolavtorvik.com

Lars Olav Torvik在http://regex.larsolavtorvik.com(如图1-5所示)建立了一个非常优秀小巧的在线正则表达式测试工具。

图1-4 RegexPlanet

首先,用户可以单击在页面上端的流派名称来选择正在使用的正则表达式流派。Lars提供了PHP PCRE、PHP POSIX和JavaScript。PHP PCRE,也就是本书中介绍的PCRE正则流派,是由PHP的preg函数使用的。POSIX是由PHP的ereg函数使用的是一种较陈旧且功能有限的正则表达式流派,在本书中并没有讨论这种流派。如果用户选择JavaScript,那么使用的就是你的浏览器中所实现的JavaScript正则表达式。

图1-5 regex.larsolavtorvik.com

在Pattern域中输入正则表达式,并在Subject域中输入目标文本。稍等片刻,在Matches域中就会显示高亮之后的正则表达式匹配的目标文本。Code域中显示把正则表达式应用到目标文本之上的一行源代码。把这段代码复制并粘贴到代码编辑器中可以节省大量时间,因为不必再费力气手动把正则表达式转换成一个文本字符串。该代码返回的任何字符串或者数组都会显示在Result域中。因为Lars使用了Ajax技术来构建他的网站,所以所有的流派都只需片刻就可以更新其结果。如果要使用该工具,电脑就必须保持联网状态,因为PHP是在服务器端进行处理的,而不是在浏览器中。

第二列给出了正则表达式命令和选项列表。这些依据你所选择的正则表达式流派而定。正则表达式命令通常包括匹配、替换和拆分操作。正则表达式选项包含常见的选项,如不区分大小写,以及与实现有关的一些选项。这些命令和选项会在第3章中讲解。

3.Nregex

http://www.nregex.com(如图1-6所示)是由David Seruyange开发的一个很简明的在线正则表达式测试工具。它支持.NET 2.0的正则流派,.NET 3.0、3.5和4.0也同样适用。

这个网页的布局看起来有些让人费解。在Regular Expression标签下面的域中输入正则表达式,并且使用其下的复选框来设定正则表达式选项。然后在底部的大输入框中键入目标文本,替换掉默认的If I just had $5.00 then "she" wouldn't be so @#$! mad.。如果你的目标是一个网页的话,那么可以把它的URL键入Load Target From URL域中,然后单击该输入域之下的Load按钮。如果目标是在硬盘上的一个文件,那么单击Browse[4](浏览)按钮,找到想要使用的文件,然后单击该输入域之下的Load按钮。

图1-6 Nregex

目标文本会重复出现在网页中心的Matches & Replacements域中,其中正则表达式的匹配会高亮显示。如果在Replacement String域中敲入一些内容,那么这里就会显示查找和替换后的结果。如果正则表达式是非法的,那么就会出现…(省略号)。

正则表达式的匹配是通过在服务器上运行的 .NET代码来完成的,所以也需要保持联网状态才能使用该网站。如果发现自动更新的速度比较慢的话,那可能是因为目标文本非常长,选中正则表达式输入域之上的Manually Evaluate Regex复选框,就会出现Evaluate按钮。单击该按钮就可以更新Matches & Replacements的显示。

4.Rubular

Michael Lovitt在http://www.rubular.com(如图1-7所示)建立了一个最小功能集的在线正则表达式测试工具。写作本书时,它允许用户在Ruby 1.8.7和Ruby 1.9.2间选择。这让你可以同时测试本书使用的Ruby 1.8和Ruby 1.9的正则表达式流派。

图1-7 Rubular

在Your regular expression下面两个正斜杠之间的文本框中输入正则表达式。你可以通过在第二个斜杠之后的小输入框中键入一个i来开启不区分大小写选项。相类似,如果需要的话还可以在同一个输入框中键入一个m来开启“点号匹配换行符”的选项。而键入im则会同时开启这两个选项。如果你是刚刚接触Ruby的话,可能会觉得这些约定看起来对用户有点儿不够友好,但是它们与用来在Ruby代码中指定正则表达式时所使用的/regex/im语法是一致的。

在Your test string文本框中输入或者粘贴目标文本。在右边会出现一个新的Match results文本框,用来显示所有正则表达式匹配高亮显示之后的目标文本。

5.myregexp.com

Sergey Evdokimov为Java开发人员创建了多个正则表达式测试工具。在http://www.myre gexp.com网站主页(如图1-8所示)提供了其中一个在线正则表达式测试工具。它是一个在浏览器中运行的Java applet(小程序)。在你的计算机上需要安装Java 4(或更新版本)运行时。这个小程序使用java.util.regex包来运行正则表达式,这个包是在Java 4中新引入的。在本书中,“Java”正则流派指的就是这个包。

图1-8 myregexp.com

在Regular Expression输入框中输入正则表达式。使用Flags菜单来设置你想用的正则选项。其中三个选项也可以直接使用复选框。

如果想要测试存在于Java代码字符串变量中的正则表达式的话,可以把整个字符串都复制到剪贴板上。在myregexp.com测试工具中,单击Edit菜单,然后选择Paste Regex from Java String(粘贴来自Java字符串的正则式)。完成了正则表达式的编辑之后,在同一个菜单中选择Copy Regex for Java Source(复制Java代码所使用的正则式)。Edit菜单对于JavaScript和XML也有类似的命令。

在正则表达式下面,有4个标签,可以用来运行4种不同的测试。

Find

在示例文本中高亮显示所有的正则表达式匹配。这些匹配是通过Java中的Matcher.find()方法找到的。

Match

测试这个正则表达式是否能够与示例文本完全匹配。如果匹配的话,那么整个文本会全部高亮。这与String.matches()和Matcher.matches()两个方法所匹配的相同。

Split

当正则表达式和示例文本一起使用时,右边的第二个文本框会显示由String.split()或者Pattern.split()所返回的字符串数组。

Replace

输入一个替代文本,右边的文本框中会显示由String.replaceAll() 或者Matcher. replaceAll()所返回的文本。

可以通过http://www.myregexp.com网页顶端的链接找到Sergey的其他正则表达式测试工具。其中一个是Eclipse的插件(plug-in)。

1.Expresso

Expresso(不要把它和富含咖啡因的浓咖啡espresso混为一谈)是用来创建和测试正则表达式的一个 .NET应用程序。可以从http://www.ultrapico.com/Expresso.htm下载它。你的计算机上必须安装有.NET Framework 2.0或者更新版本。

从网站下载的是一个60天免费试用版。在试用期过后,必须注册该软件,否则Expresso就(大体上)无法使用了。注册码通过电子邮件发送。

Expresso会显示一个类似图1-9所示的屏幕。用来输入正则表达式的Regular Expression文本框是始终保留的。它并不会进行任何语法着色。Regex Analyzer框则会为正则表达式自动构造一个简要的英语语言分析。它同样是始终保留的。

在Design Mode(设计模式)下,可以在屏幕的底部设置诸如“Ignore Case”(忽略大小写)这样的匹配选项。屏幕空间的大部分被一排标签页所占据,可以在此选择想要插入的正则表达式记号。如果你拥有两个显示器,或者一个大的显示器,可以单击Undock按钮来使这行标签页都悬浮起来。接着仍然可以在另一模式(Test Mode)下构建正则表达式。

在Test Mode(测试模式)下,可以在屏幕左下角输入或者粘贴示例代码。然后,单击Run Match按钮,就可以在Search Results文本框中得到所有匹配的列表。这里并不会对示例文本应用任何的高亮显示。在结果中单击一个匹配就可以选中在示例文本中对应的匹配。

Expression Library会给出样例正则表达式的列表,以及最近使用的正则表达式列表。每次按下Run Match的时候,当前的正则表达式都会添加到这个列表中,可以通过在主菜单工具条上的Library菜单来编辑这个表达式库。

图1-9 Expresso

2.The Regulator

可以从http://sourceforge.net/projects/regulator下载的The Regulator对佩戴水中呼吸器潜水或是使用煤气罐来说并不安全[5],它是另外一个用来创建和测试正则表达式的 .NET应用。它的最新版本要求 .NET 2.0或者更新版本。你还可以下载到用于 .NET 1.x的较早版本。The Regulator是开源软件,不需要付钱或者注册。

The Regulator会在一个屏幕(如图1-10所示)中完成所有的工作。New Document标签页是用来输入正则表达式的地方。语法着色会自动生效,但是在正则表达式中的语法错误却不会突出显示。单击鼠标右键可以从一个菜单中选择想要添加的正则表达式记号,也可以通过主工具条之上的按钮来设置正则表达式选项。这些图标看起来会有些费解,可以让鼠标稍作停留,等待提示出现,就能看到每个按钮可以设置什么选项了。

在正则表达式区域下面的右边,单击Input按钮就会显示可以用来粘贴样本文本的区域。如果想要进行查找和替换操作的话,可以单击Replace with按钮来键入替代文本。在正则表达式下面偏左的地方,你会看到该正则表达式操作的结果。它的结果不会进行自动更新;必须单击工具条中的Match、Replace或Split按钮才能更新结果。而且,它也不会对输入应用高亮显示。单击结果中的一个匹配,可以看到要它在目标文本中的位置。

图1-10 The Regulator

Regex Analyzer面板展示的是对正则表达式进行的简单的语言分析,它既不是自动的,也不能逐步互动。要想更新这个分析结果,需要在View菜单中选择Regex Analyzer,即使它已经显示也需要这样做。如果仅仅单击分析结果,只有文本指针会移动。

3.SDL Regex Fuzzer

SDL Regex Fuzzer这个含混的(fuzzy)名字没有明显表示出它的用途。微软公司宣称它是“帮助测试正则表达式中潜在的拒绝服务漏洞的工具”。可以从http://www.microsoft. com/ n-us download details.aspx?id=20095免费下载。需要安装.NET 3.5来运行它。

SDL Regex Fuzzer真正所做的是,检查是否存在一个可以使正则表达式需要指数级时间来执行的目标字符串。本书中我们称这为“灾难性回溯”。我们会在实例2.15中详细讲解这一点,并提供了一种可用的解决方案。简单说,引起灾难性回溯的正则式会让应用程序停止响应或是崩溃。如果程序是服务器应用,这可能会导致拒绝服务攻击。

图1-11显示了SDL Regex Fuzzer的一个测试结果。在Step 1中我们粘贴了实例2.15中的正则表达式。因为这个表达式无法匹配非ASCII码字符,所以无需在Step 2中选择All ASCII characters (所有ASCII码字符) 这一选项。否则,则应选择。在Step 3中我们保留默认的100次循环。单击Step 4的Start按钮,大约5秒后,SDL Regex Fuzzer显示了一个样例字符串,这个字符串会使正则式在.NET 3.5中执行失败。

图1-11 SDL Regex Fuzzer

遗憾的是,这个工具的实用性非常有限,因为它只支持.NET正则语法的一个小子集。而当我们试图测试实例2.15中的原始解决方法时,遇到了图1-12所示的错误消息,即便该正则式明显无法通过测试。正确理解实例2.15中所讨论的概念,是确保应用程序不被复杂的正则表达式拖垮的唯一途径。

图1-12 SDL Regex Fuzzer局限性

grep这个名字是从g/re/p命令推衍而来的,这个命令在Unix文本编辑器ed中用于正则表达式查找,而ed则是最早支持正则表达式的应用之一。该命令非常流行,结果所有的UNIX系统中现在都包含一个专门的grep工具以便在文件中进行正则表达式查找。如果你在使用UNIX、Linux或者OS X,那么在终端窗口中键入man grep命令就可以学习这个命令的全部知识。

下面的3个工具是用来实现与grep相同的功能的Windows应用程序,而且它们还添加了额外的功能。

1.PowerGREP

由本书作者之一Jan Goyvaerts所开发的PowerGREP,可能是在Microsoft Windows平台上可用到的功能最为丰富的grep工具(如图1-13所示)。PowerGREP使用一种定制的正则表达式流派,它兼具本书中介绍的各流派中最好的特性。这种流派在RegexBuddy中称为“JGsoft”。

图1-13 PowerGREP

要执行一次快速的正则表达式查找,只需在Action菜单中选择Clear,并在Action面板上的Search框中输入正则表达式。在File Selector面板上单击一个文件夹,然后在File Selector菜单中选择Include File or Folder或Include Folder and Subfolders。接着在Action菜单中选择Execute就可以进行查找。

要执行一次查找和替换操作,在清除了上述操作之后,在Action面板左上角处的action type下拉列表中选择search-and-replace。Search框下即会显示一个Replace框,在这里输入替代文本。其余所有的步骤都与查找功能完全相同。

PowerGREP具有独特的能力,可以在同一时刻使用最多5个正则表达式列表,在每个列表中可以包含任意数目的正则表达式。虽然上面两段已经给出了足够的信息,让你可以像使用其他任何grep工具一样执行一些简单的搜索,但是要发挥PowerGREP的全部潜力则需要多花点儿时间通读一下该工具的详细文档。

PowerGREP可以在Windows 2000/XP/Vista/7/8上运行。可以从http://www.powergrep. com/PowerGREPCookbook.exe下载免费评估版本。除了保存结果和库之外,试用版包含了可以实际使用15天的全部功能。尽管试用版不能保存在Results面板上显示的结果,但是它也和完整版本一样,会执行查找和替换操作修改所有文件。

2.Windows Grep

Windows Grep(http://www.wingrep.com)是在Windows平台上最古老的grep工具之一。它的年代可以从它的用户界面中看出一点儿端倪(如图1-14所示),但它的确可以实现他所标榜的功能。它支持一种功能有限的正则表达式流派,这种流派被称作POSIX ERE。对于它支持的功能,它所使用的语法与本书中介绍的流派是一样的。Windows Grep是一个共享软件,这意味着你可以免费下载它,但是如果希望长时间使用,就需要付费。

图1-14 Windows Grep

要想执行搜索,在Search菜单中选择Search。接下来出现的屏幕将会根据你在Options菜单中所选择的是Beginner Mode(初学者模式)或是Expert Mode(专家模式)而有所不同。初学者会看到逐步向导,而专家则会看到标签页对话框。

设置好搜索之后,Windows Grep会立即执行它,并向你展示一个在其中找到匹配的文件列表。单击一个文件就可以在底部面板中看到其中的匹配,而双击一个文件会打开该文件。在View菜单中选择All Matches会使底部面板显示所有内容。

如果想要执行查找和替换,只需要在Search菜单中选择Replace即可。

3.RegexRenamer

RegexRenamer(如图1-15所示)实际上并不是一个grep工具。它并不查找文件的内容,而是查找和替换文件的名称。可以从http://regexrenamer.sourceforge.net下载该工具。RegexRenamer要求安装Microsoft .NET Framework2.0或者更新版本。

在Match框中键入正则表达式,并在Replace框中键入替代文本。单击/i可以打开不区分大小写选项,单击/g则会替换每个文件名中的所有匹配,而不只是替换第一个匹配。选择/x会打开宽松排列(free-spacing)的语法选项,这并不是很有用,因为只有一行空间可以输入正则表达式。

使用左边的树可以选择包含你想要重命名的文件的文件夹。在右上角,可以设置一个文件名通配符掩码或者正则表达式过滤器。这可以限制“查找和替换”正则表达式所应用的文件列表。与其试图只使用一个正则表达式来完成所有工作,更方便的做法是用一个正则表达式进行过滤,用另一个正则表达式进行替换。

图1-15 RegexRenamer

大多数现代的文本编辑器都至少支持基本的正则表达式。在查找或者查找和替换面板上,你通常会发现一个复选框可以打开正则表达式模式。有些编辑器,如EditPad Pro,也会使用正则表达式来完成各种文本处理的功能,如语法高亮显示或是类和函数列表等。每个编辑器所带的文档会详细讲解所有这些功能。下面列出了一些支持正则表达式的常用文本编辑器。

[1] Jeffrey Friedl在他的博客 http://regex.info/blog/2006-09-15/247中探讨了这句话的来源和历史。

[2] 本书中将“Regular Expression”翻译为“正则表达式”,“regex”、“regexp”或者“regexes”则简称为“正则式”或“正则”。——译者注

[3] 即已发布的Visual Studio 2012。——译者注

[4] 显示文字依浏览器语言而定。——译者注

[5] regulator有调节阀之意。——译者注


Jan Goyvaerts运营着Just Great Software公司,他在这家公司设计和开发了多款非常流行的正则表达式软件。他的产品包括RegexBuddy——世界上唯一可以模拟15种正则表达式流派特性的正则表达式编辑器,以及PowerGREP——Microsoft Windows平台上功能最强大的grep工具。

Steven Levithan是Facebook的JavaScript工程师。他拥有15年的编程经验,曾在东京、华盛顿、巴格达和硅谷工作过。Steven也是顶尖的JavaScript正则表达式专家,曾创建多个开源正则表达式工具,包括RegexPal和XRegExp库。


本书封面图片是一只麝鼩(英文名musk shrew,俗称铁鼠,鼩鼱科,麝鼩属)。麝鼩可以分为多种,包括白齿和红齿的鼩鼱、灰麝鼩和红麝鼩。鼩鼱原产于非洲南部和印度。

虽然不同种类鼩鼱的体态特征不同,但是所有鼩鼱都拥有很多共同点。例如,鼩鼱被认为是世界上最小的食虫动物,所有鼩鼱都是短腿,每只脚有5个脚趾,长鼻子,触觉毛。不同种类鼩鼱牙齿的颜色不同(主要是白齿鼩鼱和红齿鼩鼱),毛发颜色不同(有红色、褐色和灰色)。

虽然鼩鼱通常以昆虫为食,但它还会吃老鼠或田野里的其他小型啮齿动物,从而帮助农民控制田里的危害。

许多麝鼩会释放出一种强烈的麝香气味(它们也因此而得名),并用这种气味来标记它们的领土。曾经有传闻说麝鼩的气味非常强烈,甚至会渗透到麝鼩所经过的任何葡萄酒或啤酒瓶中,从而把酒也染上麝香的气味,但后来这个传闻被证明是假的。

封面的图片来源于Lydekker的Royal Natural History



相关图书

云原生测试实战
云原生测试实战
Kubernetes快速入门(第2版)
Kubernetes快速入门(第2版)
Kubernetes零基础实战
Kubernetes零基础实战
深入浅出Windows API程序设计:核心编程篇
深入浅出Windows API程序设计:核心编程篇
深入浅出Windows API程序设计:编程基础篇
深入浅出Windows API程序设计:编程基础篇
云原生技术中台:从分布式到云平台设计
云原生技术中台:从分布式到云平台设计

相关文章

相关课程