Perl 正则表达式
Perl 内置的模式匹配让你能够简便高效地搜索大量的数据。不管你是在一个巨型的商业门户站点上用于扫描每日感兴趣的珍闻报道,还是在一个政府组织里用于精确地描述人口统计(或者人类基因组图),或是在一个教育组织里用于在你的 web 站点上生成一些动态信息,Perl 都是你可选的工具。这里的一部分原因是 Perl 的数据库联接能力,但是更重要的原因是 Perl 的模式匹配能力。如果你把“文本”的含义尽可能地扩展,那么可能你做的工作中有 90% 是在处理文本。这个领域实在就是 Perl 的最初专业,而且一直是 Perl 的目的——实际上,它甚至是 Perl 的名字:Practical Extraction and Report Language (实用抽取和报表语言)。Perl 的模式提供了在堆积成山的数据中扫描数据和抽取有用信息的强大工具。
你可以通过创建一个正则表达式(或者叫 regex)来声明一个模式,然后 Perl 的正则表达式引擎(我们在本章余下的部分称之为“引擎”)把这个正则表达式拿过并判断模式是否(以及如何)和你的数据相匹配。因为你的数据可能大部分由文本字串组成,所以你没有理由不用正则表达式搜索和替换任意字节序列,甚至有些你认为是“二进制”的数据也可以用正则处理。对于 Perl 而言,字节只不过碰巧是那些数值小于 256 的自然数而已。(更多相关内容见第十五章,Unicode。)
如果你通过别的途径已经知道正则表达式了,那么我们必须先警告你在 Perl 里的正则表达式是有些不同的。首先,理论上来讲,它们并不是完全“正则”的,这意味着 Perl 里的正则可以处理比计算机科学课程里教的正则表达式更多的事情。第二,因为它们在 Perl里用得实在是太广泛了,所以在这门语言里,它们有属于自己的特殊的变量,操作符,和引用习惯;这些东西都和语言本身紧密地结合在一起。而不象其他语言那样通过库松散地组合在一起。Perl 的程序员新手常常徒劳地寻找地这样的函数:
match( $string, $pattern );
subst( $string, $pattern, $replacement );
要知道在 Perl 里,匹配和子串都是非常基本的任务,所以它们只是单字符操作符:m/PATTERN/ 和 s/PATTERN/REPLACEMENT/(缩写为 m// 和 s///)。它们不仅语法简单,而且还象双引号字串那样分析,而不只是象普通操作符那样处理;当然它们的操作还是象操作符的,所以我们才叫它们操作符。你在本章通篇都会看到这些操作符用于匹配字串。如果字串的一部分匹配了模式,我们就说是一次成功的模式匹配。特别是在你用 s/// 的时候,成功匹配的部分将被你在 REPLACEMENT 里声明的内容代替。
本章所有的内容都是有关如何制作和使用模式的。Perl 的正则表达式非常有效,把许多含义包含到了一个很小的表达式里。所以如果你想直接理解一个很长的模式,那很有可能被吓着。不过如果你能把长句分解成短句,并且还知道引擎如何解释这些短句,那你就能理解任何正则表达式。一行正则表达式相当于好几百行 C 或者 JAVA 程序并不罕见。正则表达式可能比一个长程序的单一一行要难理解,但是如果从整体来看,正则表达式通常要比很长的程序要好理解。你只需要提前知道这些事情就可以了。