About the Examples
本章包括了一些常见的问题——验证用户的输入数据,处理E-mail header(电子邮件头),把纯文本数据转换为超文本格式(HTML),通过这些问题,你将真正见识到正则表达式的世界。在构造正则表达式时,我会做些尽可能详细的讲解,提供一些启示。在这个过程中,我们会见到一些 egrep 没有提供的结构和特性,也会专门花很多篇幅来探讨其他重要的概念。
在本章的末尾及下面的各章中,我会使用各种语言,包括 PHP、Java 和 VB.NET,但是本章中我们主要使用的还是Perl。这些语言,当然也包括其他许多语言,对正则表达式的操纵能力都远远强于egrep,所以使用其中任何一种作为示范都会让我们见到许多有趣的内容。我选择以Perl开始,主要是因为,在所有流行的语言中Perl对正则表达式的支持很完整,且易于使用。而且,Per还提供了许多其他紧凑的数据处理结构(data-handling constructs),能够减少所需的“简单重复劳动”(dirty work),以便我们把精力集中到正则表达式上。
第 2 页出现的文件检查的程序很好地说明了这种能力,我需要用这个程序来确定每个文件中‘ResetSize’出现的次数与‘SetSize’出现的次数是否一样多。我选择的语言是Perl,命令如下:
%perl-0ne'print “$ARGV/n” if s/ResetSize//ig!=s/SetSize//ig'*(我并不奢望你现在就能明白这条命令——我只希望你能注意到这条命令有多简洁。)
我喜欢Perl,但现在讨论的主题不是Perl。请记住,本章的重点是正则表达式。这有点儿像计算机系的教授在第一学年的课堂上说的“你们将会在这里学习计算机科学知识,但我们选择用Pascal语言作为学习的工具”(注1)。
因为本章并不假设读者已经懂得Perl,所以我会做些必要的讲解,让你明白这些例子(第7章讲解Perl的本质的细节,它假设读者懂得一些基本的知识)。即使你曾经用过好几门语言,Perl也可能让你觉得奇怪,因为它的语法极精炼,语意又极丰富。为了让这些例子更清楚,我不会使用 Perl 提供的这些特性,而是用一种更普通的近乎伪码的风格来展示这些程序。虽然算不上“蹩脚”,但这些例子也不符合Perl的编程风格。不过,我们将通过它们认识到正则表达式的重要作用。
Perl简单入门
A Short Introduction to Perl
Perl是一门功能强大的脚本语言,诞生于20世纪80年代末期,其思想主要来自其他的编程语言和工具。Perl关于文本处理和正则表达式的许多概念来自两种专业化的语言awk和sed,它们都非常不同于“传统”的语言,例如C和Pascal。
Perl 可以应用于许多平台,包括 DOS/Windows、MacOS、OS/2、VMS 和 Unix。它的文本处理能力极其强大,是关于Web的处理中最常使用的工具。如果要获得对应你的机器版本的Perl,请参考www.perl.com。
本书是为Perl的5.8版而写的,不过本章的例子可以在5.005以后的版本上使用。
现在来看一个简单的例子:
执行这段程序,结果是:
30 C is 86 F.
$fahrenheit和$celsius之类的普通变量一般以$开头,可以保存一个数值或者任意长度的文本(在本例中只保存了数值)。从#到行尾都是注释。
如果你曾经使用过C、C#或者Java、VB.NET,你可能无法理解在Perl中变量居然能够出现在双引号包围的字符串中。在字符串“$celsius C is $fahrenheit F./n”中,每个变量都会被它的实际值所取代。在本例中,结果就是打印出来的字符串(/n代表换行)。
Perl也提供了跟其他流行的语言类似的控制结构:
在条件为真(即$celsius <=45)时,while循环控制的部分会重复执行。把这段代码写入到一个程序中,例如temps,我们可以直接从命令行运行它。
下面是运行的结果:
-w参数并不是运行所必须的,与正则表达式也没有直接的联系。它只是告诉 Perl,仔细检查我们的程序,在 Perl 认为可疑的地方发出警报(例如没有初始化的变量之类——在 Perl中,变量不需要事先声明就能使用)。在这里加上这个参数,只是因为它是一种良好的习惯。
好了,这就是Perl的简单入门。下面我们来看在Perl中如何使用正则表达式。