本节书摘来自异步社区《正则表达式经典实例(第2版)》一书中的第1章,第1.3节,作者: 【美】Jan Goyvaerts , Steven Levithan著,更多章节内容可以访问云栖社区“异步社区”公众号查看
1.3 正则表达式工具
除非已经拥有了相当长的使用正则表达式编程的经验,否则建议你先在一个工具中试验一下正则表达式,而不是直接在源代码中使用它们。本章和第2章中提供的正则表达式示例都是原始正则表达式,其中并不包含编程语言(即使是Unlx shell)所必需的额外的转义符号。因此可以直接把这些正则表达式输入到一个应用程序的查找框中。
第3章讲解如何把正则表达式整合到源代码中。把一个字面的(literal)正则表达式作为一个字符串引用,会让它更加难懂,因为字符串的转义规则会与正则表达式的转义规则混杂在一起。我们在实例3.1才会开始讲解这些内容。一旦理解了正则表达式的基本知识,你就能够从无数的反斜杠的背后看到“森林”。
本节要介绍的工具同样会提供调试和语法检查的功能,以及在绝大多数编程环境中并不会获得的其他反馈信息。因此,在开发应用程序时研究正则表达式的时候,你可能会发现在把一个复杂的正则表达式插入到程序中之前,首先使用这类工具试验一下可能会非常有用。
1.3.1 RegexBuddy
在本书写作之时,RegexBuddy(如图1-1所示)是用来创建、测试和实现正则表达式功能最为丰富的工具。它拥有独特的能力,可以仿真本书中讲到的所有正则表达式的流派,甚至可以在不同的流派之间进行转换。
RegexBuddy是由本书作者之一Jan Goyvaerts设计和开发的。设计和开发RegexBuddy使Jan成为了正则表达式的专家;由于使用了RegexBuddy,本书的另一位作者Steven迷恋上了正则表达式,最终向O’Reilly出版社建议出版这本书。
如果觉得屏幕截图(如图1-1所示)看起来比较繁杂,那是因为我们特意并排列出了大多数的面板,用来展示RegexBuddy的强大功能。实际上默认的视图会把所有的面板都很简洁地压缩成一行标签。另外,你还可以选择把一些面板拖动到另外一台显示器上。
要想尝试本书中给出的某个正则表达式,只需要把它键入RegexBuddy窗口上端的编辑框中。RegexBuddy会自动对正则表达式应用语法着色,从而使错误和括号不匹配的情形更容易看清楚。
在键入正则表达式的同时,Create面板会自动构造一个用英语描述的详细分析。在该正则表达式的树中双击任意的描述,可以编辑正则表达式的对应部分。你还可以手动向正则表达式中添加新的部分,或者通过单击Insert Token按钮从菜单中选择想要的操作。例如,如果不记得肯定型顺序环视(positive lookahead)的复杂语法,可以依靠RegexBuddy来帮助添加正确的字符。
在Test面板上可以键入或者粘贴一些示例文本。当Highlight按钮激活的时候,RegexBuddy会自动高亮显示与正则表达式匹配的文本。
最经常会用到的一些按钮如下。
单击上述任意一个按钮,并选择Update Automatically(自动更新),就可以让RegexBuddy在编辑正则表达式或者目标文本的时候,同步显示动态结果。
要想看到正则表达式到底会(或者不会)如何执行,在Test面板上单击一个高亮显示的匹配或者是正则表达式没有能够产生匹配的地方,然后单击Debug按钮。RegexBuddy会转到Debug面板上,逐步展示整个匹配的过程。单击调试器输出的任意地方,就可以查看哪些正则表达式记号匹配了你所单击的文本。单击正则表达式则可以在调试器中高亮显示正则表达式的该部分。
在Use面板上,选择你最喜欢的编程语言。然后,选择一个功能就可以立即生成实现该正则表达式的源代码。RegexBuddy的源代码模板可以使用内置的模板编辑器进行完整编辑。你还可以添加新的功能甚至是新的语言,或者是修改内置的模板。
如果想在一个更大的数据集上测试正则表达式,转到GREP面板上就可以在任意数量的文件和文件夹上进行查找(以及替换)。
当你在维护的源代码中发现一个正则表达式的时候,可以把它复制到剪贴板上,包括其中用于分隔的引号和斜杠。在RegexBuddy中,单击顶端的Paste按钮,并选择你的编程语言字符串风格。该正则表达式就会以原始正则表达式的形式出现在RegexBuddy中,而字符串字面量(string literal)必需的额外引号和转义符号都被去掉了。使用顶部的Copy按钮就可以创建一个按照你所要求的语法的字符串,然后可以把它重新粘贴回源代码中。
经验增长以后,用户就可以在Library面板上构建起一个便于使用的正则表达式库。在保存正则表达式的时候,别忘了添加对应的详细的描述与测试对象。即使是对专家来说,正则表达式也可能会是难以捉摸的。
如果确实无法搞明白一个正则表达式是怎么回事,可以单击Forum面板,然后单击Login按钮。如果已经购买了RegexBuddy,就会出现登录屏幕。单击OK,就会立即连接到RegexBuddy用户论坛中。Steven和Jan经常会出现在这个论坛回答用户的问题。
1.3.2 RegexPal
RegexPal(如图1-2所示)是由本书的作者之一Steven Levithan所创建的在线正则表达式测试工具。你所需要的仅仅是一个版本较新的网页浏览器。RegexPal全部是由JavaScript编写的。因此,它只支持JavaScript正则流派,这与你用来访问它的网页浏览器中所实现的正则表达式一样。
现在,你可以在中间的大输入框中键入或者粘贴一段样本文本。RegexPal会自动高亮与正则表达式匹配的文本。
在这个工具中并不需要单击任何按钮,因此RegexPal是最为方便的在线正则表达式测试工具之一。
1.3.3 RegexMagic
RegexMagic(如图1-3所示)是另一款由Jan Goyvaerts设计和开发的工具软件。RegexBuddy的目标是可以更为容易地处理正则表达式语法,而RegexMagic则主要设计给那些不愿意接触正则表达式语法,更不肯读500页正则表达式图书的人。
在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
1.3.4 更多正则表达式在线测试工具
创建一个简单的正则表达式在线测试工具并不困难。如果你拥有一些基本的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所示)建立了一个非常优秀小巧的在线正则表达式测试工具。
首先,用户可以单击在页面上端的流派名称来选择正在使用的正则表达式流派。Lars提供了PHP PCRE、PHP POSIX和JavaScript。PHP PCRE,也就是本书中介绍的PCRE正则流派,是由PHP的preg函数使用的。POSIX是由PHP的ereg函数使用的是一种较陈旧且功能有限的正则表达式流派,在本书中并没有讨论这种流派。如果用户选择JavaScript,那么使用的就是你的浏览器中所实现的JavaScript正则表达式。
在Pattern域中输入正则表达式,并在Subject域中输入目标文本。稍等片刻,在Matches域中就会显示高亮之后的正则表达式匹配的目标文本。Code域中显示把正则表达式应用到目标文本之上的一行源代码。把这段代码复制并粘贴到代码编辑器中可以节省大量时间,因为不必再费力气手动把正则表达式转换成一个文本字符串。该代码返回的任何字符串或者数组都会显示在Result域中。因为Lars使用了Ajax技术来构建他的网站,所以所有的流派都只需片刻就可以更新其结果。如果要使用该工具,电脑就必须保持联网状态,因为PHP是在服务器端进行处理的,而不是在浏览器中。
第二列给出了正则表达式命令和选项列表。这些依据你所选择的正则表达式流派而定。正则表达式命令通常包括匹配、替换和拆分操作。正则表达式选项包含常见的选项,如不区分大小写,以及与实现有关的一些选项。这些命令和选项会在第3章中讲解。
3.Nregexhttp://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按钮。如果目标是在硬盘上的一个文件,那么单击Browse1FF(浏览)按钮,找到想要使用的文件,然后单击该输入域之下的Load按钮。
目标文本会重复出现在网页中心的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的正则表达式流派。
在Your regular expression下面两个正斜杠之间的文本框中输入正则表达式。你可以通过在第二个斜杠之后的小输入框中键入一个i来开启不区分大小写选项。相类似,如果需要的话还可以在同一个输入框中键入一个m来开启“点号匹配换行符”的选项。而键入im则会同时开启这两个选项。如果你是刚刚接触Ruby的话,可能会觉得这些约定看起来对用户有点儿不够友好,但是它们与用来在Ruby代码中指定正则表达式时所使用的/regex/im语法是一致的。
在Your test string文本框中输入或者粘贴目标文本。在右边会出现一个新的Match results文本框,用来显示所有正则表达式匹配高亮显示之后的目标文本。
5.myregexp.com
Sergey Evdokimov为Java开发人员创建了多个正则表达式测试工具。在http://www.myregexp.com
网站主页(如图1-8所示)提供了其中一个在线正则表达式测试工具。它是一个在浏览器中运行的Java applet(小程序)。在你的计算机上需要安装Java 4(或更新版本)运行时。这个小程序使用java.util.regex包来运行正则表达式,这个包是在Java 4中新引入的。在本书中,“Java”正则流派指的就是这个包。
在Regular Expression输入框中输入正则表达式。使用Flags菜单来设置你想用的正则选项。其中三个选项也可以直接使用复选框。
如果想要测试存在于Java代码字符串变量中的正则表达式的话,可以把整个字符串都复制到剪贴板上。在myregexp.com测试工具中,单击Edit菜单,然后选择Paste Regex from Java String(粘贴来自Java字符串的正则式)。完成了正则表达式的编辑之后,在同一个菜单中选择Copy Regex for Java Source(复制Java代码所使用的正则式)。Edit菜单对于JavaScript和XML也有类似的命令。
在正则表达式下面,有4个标签,可以用来运行4种不同的测试。
1.3.5 更多桌面正则表达式测试工具
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菜单来编辑这个表达式库。
2.The Regulator
可以从http://sourceforge.net/projects/regulator
下载的The Regulator对佩戴水中呼吸器潜水或是使用煤气罐来说并不安全2FF,它是另外一个用来创建和测试正则表达式的 .NET应用。它的最新版本要求 .NET 2.0或者更新版本。你还可以下载到用于 .NET 1.x的较早版本。The Regulator是开源软件,不需要付钱或者注册。
The Regulator会在一个屏幕(如图1-10所示)中完成所有的工作。New Document标签页是用来输入正则表达式的地方。语法着色会自动生效,但是在正则表达式中的语法错误却不会突出显示。单击鼠标右键可以从一个菜单中选择想要添加的正则表达式记号,也可以通过主工具条之上的按钮来设置正则表达式选项。这些图标看起来会有些费解,可以让鼠标稍作停留,等待提示出现,就能看到每个按钮可以设置什么选项了。
在正则表达式区域下面的右边,单击Input按钮就会显示可以用来粘贴样本文本的区域。如果想要进行查找和替换操作的话,可以单击Replace with按钮来键入替代文本。在正则表达式下面偏左的地方,你会看到该正则表达式操作的结果。它的结果不会进行自动更新;必须单击工具条中的Match、Replace或Split按钮才能更新结果。而且,它也不会对输入应用高亮显示。单击结果中的一个匹配,可以看到要它在目标文本中的位置。
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中执行失败。
遗憾的是,这个工具的实用性非常有限,因为它只支持.NET正则语法的一个小子集。而当我们试图测试实例2.15中的原始解决方法时,遇到了图1-12所示的错误消息,即便该正则式明显无法通过测试。正确理解实例2.15中所讨论的概念,是确保应用程序不被复杂的正则表达式拖垮的唯一途径。
1.3.6 grep
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”。
要执行一次快速的正则表达式查找,只需在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是一个共享软件,这意味着你可以免费下载它,但是如果希望长时间使用,就需要付费。
要想执行搜索,在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.3.7 常见的文本编辑器
大多数现代的文本编辑器都至少支持基本的正则表达式。在查找或者查找和替换面板上,你通常会发现一个复选框可以打开正则表达式模式。有些编辑器,如EditPad Pro,也会使用正则表达式来完成各种文本处理的功能,如语法高亮显示或是类和函数列表等。每个编辑器所带的文档会详细讲解所有这些功能。下面列出了一些支持正则表达式的常用文本编辑器。
- BBEdit(PCRE)
- Boxer Text Editor(PCRE)
- Dreamweaver(JavaScript)
- EditPad Pro(组合了本书中介绍的流派中最好部分的一种定制流派;在RegexBuddy中称作是“JGsoft”)
- Multi-Edit(PCRE,需要选择“Perl”选项)
- Nisus Writer Pro(Ruby 1.9 [Oniguruma])
- Notepad++(PCRE)
- NoteTab(PCRE)
- UltraEdit(PCRE)
- TextMate(Ruby 1.9 [Oniguruma])