一个正则表达式是一个特定的格式化模式,可以用来找出一个字符串在另一个字符串中的使用情况。几个编程语言,包括Visual Basic,Perl,JavaScript和PHP都支持正则表达式,希望在这篇入门指导的结束,Mitchell(作者自己)可以让你在PHP程序中能应用一些基本的正则表达式。正则表达式是在各种各样的程序语言中突出的古怪特征中的一种,但是由于它们看起来是很难的一个概念,所以很多开发者就把它们放到了角落里,忘记了它们的存在。
让我们先来看看什么是正则表达式,为什么你要在PHP程序中用到它们。
什么是正则表达式?
你对从一个不错的老的基于控制的文本编辑器中分离出像BBEdit和notepad的程序,有什么看法呢?两个都支持文本输入,可以让你保存文本到文件中,但是现在的文本编辑器也支持其它功能,包括查找–代替工具,这让编辑一个文本文件相当容易。
正则表达式也是相似的,只是更好一些。正则表达式可以被认为一个极其高级的查找-替换工具,让我们从痛苦中摆脱出来:不必再写定制的数据确认例子来检查电子邮件地址或者来确认电话号码的格式是正确的,如此等等。
任何程序中最普通的函数之一就是数据有效性检查,PHP捆绑了一些文本检查函数,允许我们用正则表达式匹配一个字符串,确认有一个空格,有一个问号,等等。
你不知道的可能是,正则表达式可以简单装备吗,当你掌握了一些正则表达式时(这个正则表达式可以用来告诉正则表达式引擎一个字符串中我们想要匹配的部分),你会自问为什么会把正则表达式扔到角落里这么久,^_^。
PHP有两套函数,用来处理两种类型的正则表达式:Perl5兼容模式,和Posix标准兼容模式。在这篇文章中我们将看看ereg函数,用遵照Posix标准的搜索表达式工作。虽然它们并没有Perl5模式那样强大,但是一种不错的学习正则表达式的方法。如果你对PHP支持的Perl5兼容正则表达式感兴趣,可以到PHP.net网站找一些关于preg函数的细节。
PHP有六个函数来处理正则表达式,它们都把一个正则表达式作为它们的第一个参数,列出如下:
ereg: 最常用的正则表达式函数, ereg 允许我们搜索跟一个正则表达式匹配的一个字符串.
ereg_replace: 允许我们搜索跟正则表达式匹配的一个字符串,并用新的字符串代替所有这个表达式出现的地方。
eregi: 和ereg几乎是一样效果,不过忽略大小写。
eregi_replace: 和ereg_replace有着一样的搜索-替换功能,不过忽略大小写.
split: 允许我们搜索和正则表达式匹配的字符串,并且以字符串集合的方式返回匹配结果.
spliti: split函数忽略大小写的版本.
为什么使用正则表达式?
如果你不断地建立不同的函数来检查或者操作字符串的一部分,现在你可能要放弃所有的这些函数,取而代之的用正则表达式。如果你对下列的问题都答“是的”,那么你肯定要考虑使用正则表达式了:
你是否正在写一些定制的函数来检查表单数据(比如在电子信箱地址中的一个@,一个点)?
你是否写一些定制的函数,在一个字符串中循环每个字符,如果这个字符匹配了一个特定特征(比如它是大写的,或者它是一个空格),那么就替换它?
除了是令人不舒服的字符串检查和操作方法,如果没有有效率地写代码,上述的两条也会使你的程序慢下来。你是否更倾向于用下面的代码检查一个电子信箱地址呢:
<?phpfunction validateEmail($email){$hasAtSymbol = strpos($email, "@");$hasDot = strpos($email, ".");if($hasAtSymbol && $hasDot)return true;elsereturn false;}echo validateEmail("mitchell@devarticles.com");?>
... 或者使用下面的代码:
<?phpfunction validateEmail($email){return ereg("^[a-zA-Z]+@[a-zA-Z]+.[a-zA-Z]+$", $email);}echo validateEmail("mitchell@devarticles.com");?>
可以肯定的是,第一个函数比较容易,而且看起来结构也不错。但是如果我们用上面的下一个版本的email地址检查函数不是更容易吗?
上面展示的第二个函数只用了正则表达式,包括了对ereg函数的一个调用。Ereg 函数返回true或者false,来声明它的字符串参数是否和正则表达式相匹配。
很多编程者避开正则表达式,只因为它们(在一些情况下)比其它的文本处理方法更慢。正则表达式可能慢的原因是因为它们涉及把字符串在内存中拷贝和粘贴,因为正则表达式的每一个新的部分都对应匹配一个字符串。但是,从我对正则表达式的经验来说,除非你在文本中几百个行运行一个复杂的正则表达式,否则性能上的缺陷都可以忽略不计,当把正则表达式作为输入数据检查工具时,也很少出现这种情况。
正则表达式语法
在你可以匹配一个字符串到正则表达式之前,你必须先建立正则表达式。开始的时候,正则表达式的语法有点古怪,表达式中的每一个短语代表某个类型的搜索特征。下列是一些最普通的正则表达式,也都对应着一个如何使用它的例子:
字符串头部
搜索一个字符串的头部,用^,例如
<?php echo ereg("^hello", "hello world!"); ?>
将返回 true, 但是
<?php echo ereg("^hello", "i say hello world"); ?>
将返回 false, 因为hello不在字符串”I say hello world”的头部。
字符串尾部
搜索字符串尾部,用$,例如:
<?php echo ereg("bye$", "goodbye"); ?>
将返回true, 但是
<?php echo ereg("bye$", "goodbye my friend"); ?>
将返回 false,因为bye不在字符串”goodbye my friend”的尾部.
任意的单个字符
搜索任意字符,用点(.),例如:
<?php echo ereg(".", "cat"); ?>
将返回true,但是
<?php echo ereg(".", ""); ?>
将返回false,因为我们的要搜索字符串没有包含字符。你可以用花括号随意告诉正则表达式引擎它要匹配多少个单个字符。如果我只想匹配5个字符,我可以这样用ereg:
<?php echo ereg(".{5}$", "12345"); ?>
上面的这段代码告诉正则表达式引擎当且仅当至少5个连续的字符出现字符串的尾部时返回true.我们也可以限制连续出现的字符的数目:
<?php echo ereg("a{1,3}$", "aaa"); ?>
在上面的例子里,我们已经告诉正则表达式引擎,我们的搜索字符串来匹配表达式,它在尾部必须有介于1和3个的”a”字符。
<?php echo ereg("a{1,3}$", "aaab"); ?>
上面的例子将不会返回true,虽然有三个”a”字符在搜索字符串里,但是它们不是在字符串的尾部。如果我们把结尾字符串匹配$从正则表达式中去掉,那么这个字符串是匹配的。
我们也可以告诉正则表达式引擎来匹配至少有确定数目的字符在一行,如果它们存在的,可以匹配更多。 我们可以这样做:
<?php echo ereg("a{3,}$", "aaaa"); ?>
零或多次重复字符
为了告诉正则表达式引擎一个字符可能存在,也可以重复,我们用*字符。这里的两个例子都将返回true.
<?php echo ereg("t*", "tom"); ?><?php echo ereg("t*", "fom"); ?>
即使第二个例子不包含”t”这个字符,但仍旧返回ture,因为*表示字符可以出现,但不是必须出现。事实上,任何普通的字符串模式都会使上面的ereg调用返回true,因为’t’字符是可选的.