PHP正则表达式

来源:互联网 发布:iosselect.js andriod 编辑:程序博客网 时间:2024/05/18 00:14

    简单的说,正则表达式是一种可以用于模式匹配和替换的强大工具。在几乎所有的基于UNIX/LINUX系统的软件工具中找到正则表达式的痕迹,例如:Perl或PHP脚本语言。此外,JavaScript这种客户端的脚本语言也提供了对正则表达式的支持,现在正则表达式已经成为了一个通用的概念和工具,被各类技术人员所广泛使用。

    在某个Linux网站上面有这样的话:"如果你问一下Linux爱好者最喜欢什么,他可能会回答正则表达式;如果你问他最害怕什么,除了繁琐的安装配置外他肯定会说正则表达式。"

    正如上面说的,正则表达式看起来非常复杂,让人害怕,大多数的PHP初学者都会跳过这里,继续下面的学习,但是PHP中的正则表达式有着可以利用模式匹配找到符合条件的字符串、判断字符串是否合乎条件或者用指定的字符串来替代符合条件的字符串等强大的功能,不学实在太可惜了……

正则表达式

正则表达式是一个非常大的题目,Perl的正则表达式的强大是闻了名的。而PHP也不弱,他继承了Perl的正则表达式法则,还有自己的一套法则。这里只说PHP自己的正则表达式。

正则表达式是最基本的元素。简单地说就是一套规则,用于去判定其它的元素是不是符合自身的规则,或者说是不是有相同的特征描述。

正则表达式的开始符:^,结尾符$,这两个符号间的是匹配的元素。如检查一个电话号码是不是打往北京的号,用正则表达式表示就是“^010$”。只要前3位区号是010,就是北京的号,后面的电话号码就不用管了。然后,用正则表达式匹配函数ereg来判断,例:

<?php

$pattern = "^010$";

$phone = "01080718828";

if(ereg($pattern, $phone))

echo "打往北京的号";

else

echo "不是打往北京的号";

?>

这就是正则表达式。北京的电话都是8位数字的,那我要知道这个号码是不是正确了?假如他按了9位号呢?如果判断正误?这就要用到正则表达式的字符簇。那么上例的正则表达式就要这样写:^010[0-9]{8}$,就能同时判断号码是不是符合规则。正则表达式有很多的应用,像LBB、VBB论坛在发贴时的所谓VBB代码LBB代码的解析,都是用正则表达式完成的。

什么是正则表达式?

 

你对从一个不错的老的基于控制的文本编辑器中分离出像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函数忽略大小写的版本.

为什么使用正则表达式?

 

      如果你不断地建立不同的函数来检查或者操作字符串的一部分,现在你可能要放弃所有的这些函数,取而代之的用正则表达式。如果你对下列的问题都答“是的”,那么你肯定要考虑使用正则表达式了:

 

你是否正在写一些定制的函数来检查表单数据(比如在电子信箱地址中的一个@,一个点)?

你是否写一些定制的函数,在一个字符串中循环每个字符,如果这个字符匹配了一个特定特征(比如它是大写的,或者它是一个空格),那么就替换它?

     除了是令人不舒服的字符串检查和操作方法,如果没有有效率地写代码,上述的两条也会使你的程序慢下来。你是否更倾向于用下面的代码检查一个电子信箱地址呢:

 

<?php

function validateEmail($email)

{

     $hasAtSymbol = strpos($email, "@");

     $hasDot = strpos($email, ".");

      if($hasAtSymbol && $hasDot)

        return true;

     else

        return false;

}

echovalidateEmail("mitchell@devarticles.com");

?>

... 或者使用下面的代码:

 

<?php

function validateEmail($email)

{

   return ereg("^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+$", $email);

}

echovalidateEmail("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’字符是可选的.

 

 

一或多次重复字符

为了告诉正则表达式引擎一个字符必须存在,也可以重复不止一次,我们用+字符,像

 

<?php echo ereg("z+", "ilike the zoo"); ?>

下面的例子也会返回true:

<?php echo ereg("z+", "ilike the zzzzzzoo!"); ?>

 

零或一次重复字符

我们也可以告诉正则表达式引擎,一个字符必须是或者只存在一次,或者没有。我们用?字符来做这项工作,就像

<?php echo ereg("c?","cats are fuzzy"); ?>

如果我们愿意,我们完全可以从上面的搜索字符串中删除’c’,这个表达式会仍旧返回true.’?’的意思是一个’c’可以出现在搜索字符串的任何地方,但不是必须的。

 

 

 

 

空格字符

为了匹配一个搜索字符串中的空格字符,我们用预定义Posix的类,[[:space]].方括号标明连续字符的相关性,”:space:”是实际要匹配的类(在这种情形下,是任何空白字符)。空白包括tab字符,新行字符,空白字符。或者,如果搜索字符串必须包含只有一个空格,而不是一个tab或者新行字符,你可以用一个空格字符(" ")。在大多数情况下,我倾向于使用":space:",因为这意味着我的意图不仅仅是单个空格字符,这点很容易被忽视。这里有一些Posix-标准预定义类,

有一些我们可以作为正则表达式的部分的一些Posix-标准预定义类,包括[:alnum:],[:digit:], [:lower:]等等。 完整的列表可以在这里查看

 

我们可以像这样匹配单个空白字符:

 

<?php echoereg("Mitchell[[:space:]]Harper", "Mitchell Harper"); ?>

我们也可以通过在表达式后用?字符来告诉正则表达式引擎匹配没有空白或者一个空白。

<?php echoereg("Mitchell[[:space:]]?Harper", "MitchellHarper"); ?>

 

模式分组

相关的模式可以在方括号里分在一起。很容易用[a-z]和[A-Z]指定只有一个小写字母或者一列大写字母以搜索字符串的一部分存在。

<?php

// 要求从第一个到最后一个都是小写字母

echo ereg("^[a-z]+$","johndoe"); // 返回true

?>

或者像

<?php

// 要求从第一个到最后一个都是大写字母

ereg("^[A-Z]+$","JOHNDOE"); // 返回 true?

?>

我们也可以告诉正则表达式引擎,我们希望或者是小写字母,或者是大写字母。我们只要把[a-z]和[A-Z]模式结合在一起就可以做到。

<?php echo ereg("^[a-zA-Z]+$","JohnDoe"); ?>

在上面的例子里,如果我们能匹配"John Doe",而不是"JohnDoe",将是非常有意义的。我们用下面的正则表达式来做这个:

^[a-zA-Z]+[[:space:]]{1}[a-zA-Z]+$

很容易搜索一个数字字符串

<?php echo ereg("^[0-9]+$","12345"); ?>

 

词语分组

不仅仅搜索模式可以分组,我们也可以用圆括号把相关的搜索词语进行分组。

<?php echoereg("^(John|Jane).+$", "John Doe"); ?>

在上面的例子中,我们有一个字符串头部字符,紧跟着"John"或者"Jane",至少有一个其它字符,然后一个字符串尾部字符。所以…

<?php echoereg("^(John|Jane).+$", "Jane Doe"); ?>

...将也匹配我们的搜索模式

 

特殊字符的情形

因为一些字符要用在一个搜索模式的明确分组或者语法上,像在(John|Jane)中的圆括号,我们需要告诉正则表达式引擎来屏蔽这些字符,加工它们使之成为被搜索字符串的一部分,而不是搜索表达式的一部分。我们所用的方法称为“字符转义”,涉及到将任何“专用符号”加上反斜杠。所以,例如,如果我想在我的搜索中包含’|’,那么我就可以这样做

<?php echoereg("^[a-zA-z]+\|[a-zA-z]+$", "John|Jane"); ?>

这里只是少量的一些你要转义的字符,你必须转义^, $, (, ), ., [, |, *, ?, +, \ and { 。

希望你现在对正则表达式实际上有多么强大有了一点点感觉了。现在让我们看两个用正则表达式来检查数据中一个字符串的例子。

 

 

 

正则表达式例子

例子1

让我们把第一个例子做的相当简单,检验一个标准的URL.一个标准的URL(没有端口号),有三个部分构成:

 

[协议]://[域名]

 

让我们从匹配URL的协议部分开始,并且让它只能用http或者ftp.我们可以用下面的正则表达式做到这点:

 

^(http|ftp)

^字符特指字符串的头部,利用圆括号把http和ftp围住,且用“或者”符号(|)将它们分开,我们告诉正则表达式引擎http和ftp两者之一必须在字符串的开头。

 

一个域名通常由www.somesite.com构成,但是可以随意选择要不要www部分。为了例子简单,我们只允许.com,.net,和.org的域名是在考虑之中的。我们最好这样对正则表达式中的域名部分表示如下:

(www\.)?.+\.(com|net|org)$

把所有的东西放在一起,我们的正则表达式就可以用作检查一个域名,如:

 

<?php

function isValidDomain($domainName)

{

 

returnereg("^(http|ftp)://(www\.)?.+\.(com|net|org)$", $domainName);

}

//真(true)

echoisValidDomain("http://www.somesite.com");

//真(true)

echoisValidDomain("ftp://somesite.com");

//假 (false)

echoisValidDomain("ftp://www.somesite.fr");

//假 (false)

echoisValidDomain("www.somesite.com");

?>

 

例子二

因为我居住在澳大利亚悉尼,让我们检查一个典型的澳大利亚国际电话号码。澳大利亚国际电话号码的格式如下:

+61x xxxx-xxxx

第一个x是区号,其它的都是电话号码。检查以'+61'开头且紧跟一个在2到9之间的区号的电话号码,我们用下面的正则表达式:

 

^\+61[2-9][[:space:]]

注意,上面的搜索模式把'+'字符用'\'转义,以便于可以在搜索中包含,不至于被解释为一个正则表达式。[2-9]告诉正则表达式引擎我们需要包含一个2到9之间的数字。[[:space:]]类则告诉正则表达式期望在这里有一个空白。

 

 

这里是电话号码剩下的搜索模式:

[0-9]{4}-[0-9]{4}$

这里没有什么不寻常的地方,我们只是告诉正则表达式引擎电话号码可用的数字,它必须是4个数字的组合,跟着一个连接符,再跟着另一个4个数字的组合,然后一个字符串尾部字符。

把完整的正则表达式放在一起,放进一个函数,我们可以用代码来检查一些澳大利亚国际电话号码:

<?php

function isValidPhone($phoneNum)

{

echo ereg("^\+61[2-9][[:space:]][0-9]{4}-[0-9]{4}$",$phoneNum);

}

// 真(true)

echo isValidPhone("+6190000-0000");

// 假(false)

echo isValidPhone("+6100000000");

//假( false)

echo isValidPhone("+61100000000");

?>

 

 

 

总结

正则表达式用一些不适合书写和重复的代码来检查一个字符串。在最后的几页里,我们已经讲解了所有的Posix标准正则表达式的基础,包括字符,分组和PHP ereg函数。我们也知道了怎么用正则表达式来检查一些PHP中简单的字符串。

3 正则表达式的基本语法:

    一个正则表达式,分为三个部分:分隔符,表达式和修饰符。

    分隔符可以是除了特殊字符以外的任何字符(比如"/!"等等),常用的分隔符是"/"。表达式由一些特殊字符(特殊字符详见下面)和非特殊的字符串组成,比如"[a-z0-9_-]+@[a-z0-9_-.]+"可以匹配一个简单的电子邮件字符串。修饰符是用来开启或者关闭某种功能/模式。下面就是一个完整的正则表达式的例子:

/hello.+?hello/is

    上面的正则表达式"/"就是分隔符,两个"/"之间的就是表达式,第二个"/"后面的字符串"is"就是修饰符。

    在表达式中如果含有分隔符,那么就需要使用转义符号"\",比如"/hello.+?\/hello/is"。转义符号除了用于分隔符外还可以执行特殊字符,全部由字母构成的特殊字符都需要"\"来转义,比如"\d"代表全体数字。

 

4 正则表达式的特殊字符:

    正则表达式中的特殊字符分为元字符、定位字符等等。

    元字符是正则表达式中一类有特殊意义的字符,用来描述其前导字符(即元字符前面的字符)在被匹配的对象中出现的方式。元字符本身是一个个单一的字符,但是不同或者相同的元字符组合起来可以构成大的元字符。

元字符:

    大括号:大括号用来精确指定匹配元字符出现的次数,例如"/pre{1,5}/"表示匹配的对象可以是"pre"、"pree"、"preeeee"这样在"pr"后面出现1个到5个"e"的字符串。或者"/pre{,5}/"代表pre出现0此到5次之间。

    加号:"+"字符用来匹配元字符前的字符出现一次或者多次。例如"/ac+/"表示被匹配的对象可以是"act"、"account"、"acccc"等在"a"后面出现一个或者多个"c"的字符串。"+"相当于"{1,}"。

    星号:"*"字符用来匹配元字符前的字符出现零次或者多次。例如"/ac*/"表示被匹配的对象可以是"app"、"acp"、"accp"等在"a"后面出现零个或者多个"c"的字符串。"*"相当于"{0,}"。

    问号:"?"字符用来匹配元字符前的字符出现零次或者1次。例如"/ac?/"表示匹配的对象可以是"a"、"acp"、"acwp"这样在"a"后面出现零个或者1个"c"的字符串。"?"在正则表达式中还有一个非常重要的作用,即"贪婪模式"。

 

     还有两个很重要的特殊字符就是"[ ]"。他们可以匹配"[]"之中出现过的字符,比如"/[az]/"可以匹配单个字符"a"或者"z";如果把上面的表达式改成这样"/[a-z]/",就可以匹配任何单个小写字母,比如"a"、"b"等等。

    如果在"[]"中出现了"^",代表本表达式不匹配"[]"内出现的字符,比如"/[^a-z]/"不匹配任何小写字母!并且正则表达式给出了几种"[]"的默认值:

[:alpha:]:匹配任何字母

[:alnum:]:匹配任何字母和数字

[:digit:]:匹配任何数字

[:space:]:匹配空格符

[:upper:]:匹配任何大写字母

[:lower:]:匹配任何小写字母

[:punct:]:匹配任何标点符号

[:xdigit:]:匹配任何16进制数字

 

另外下面这些特殊字符在转义符号"\"转义后代表的含义如下:

s:匹配单个的空格符

S:用于匹配除单个空格符之外的所有字符。

d:用于匹配从0到9的数字,相当于"/[0-9]/"。

w:用于匹配字母,数字或下划线字符,相当于"/[a-zA-Z0-9_]/"。

W:用于匹配所有与w不匹配的字符,相当于"/[^a-zA-Z0-9_]/"。

D:用于匹配任何非10进制的数字字符。

.:用于匹配除换行符之外的所有字符,如果经过修饰符"s"的修饰,"."可以代表任意字符。

 

    利用上面的特殊字符可以很方便的表达一些比较繁琐的模式匹配。例如"/\d0000/"利用上面的正则表达式可以匹配万以上,十万一下的整数字符串。

 

定位字符:

    定位字符是正则表达式中又一类非常重要的字符,它的主要作用是用于对字符在匹配对象中的位置进行描述。

^:表示匹配的模式出现在匹配对象的开头(和在"[]"里面不同)

$:表示匹配的模式出现在匹配对象的末尾

空格:表示匹配的模式出现在开始和结尾的两个边界之一

"/^he/":可以匹配以"he"字符开头的字符串,比如hello、height等等;

"/he$/":可以匹配以"he"字符结尾的字符串即she等;

"/ he/":空格开头,和^的作用一样,匹配以he开头的字符串;

"/he /":空格结束,和$的作用一样,匹配以he结尾的字符串;

"/^he$/":表示只和字符串"he"匹配。

 

括号:

    正则表达式除了可以用户匹配,还可以用括号"()"来记录需要的信息,储存起来,给后面的表达式读取。比如:

/^([a-zA-Z0-9_-]+)@([a-zA-Z0-9_-]+)(.[a-zA-Z0-9_-])$/

就是记录邮件地址的用户名,和邮件地址的服务器地址(形式为username@server.com之类的),在后面如果想要读取记录下来的字符串,只是需要用"转义符+记录的次序"来读取。比如"\\1"就相当于第一个"[a-zA-Z0-9_-]+","\\2"相当于第二个([a-zA-Z0-9_-]+),"\\3"就是第三个(.[a-zA-Z0-9_-])。但是在PHP中,"\"是一个特殊的字符,需要转义,所以"\1"到了PHP的表达式中就应该写成"\\\\1"。

其他特殊符号:

"|":或符号"|"和PHP里面的或一样,不过是一个"|",而不是PHP的两个"||"!意思就是可以是某个字符或者另一个字符串,比如"/abcd|dcba/"可能匹配"abcd"或者"dcba"。

 

5 贪婪模式:

前面在元字符中提到过"?"还有一个重要的作用,即"贪婪模式",什么是"贪婪模式"呢?

比如我们要匹配以字母"a"开头字母"b"结尾的字符串,但是需要匹配的字符串在"a"后面含有很多个"b",比如"a bbbbbbbbbbbbbbbbb",那正则表达式是会匹配第一个"b"还是最后一个"b"呢?如果你使用了贪婪模式,那么会匹配到最后一个"b",反之只是匹配到第一个"b"。

    使用贪婪模式的表达式如下:

/a.+?b/

/a.+b/U

不使用贪婪模式的如下:

/a.+b/

上面使用了一个修饰符U,详见下面的部分。

 

6 修饰符:

    在正则表达式里面的修饰符可以改变正则的很多特性,使得正则表达式更加适合你的需要(注意:修饰符对于大小写是敏感的,这意味着"e"并不等于"E")。正则表达式里面的修饰符如下:

i :如果在修饰符中加上"i",则正则将会取消大小写敏感性,即"a"和"A" 是一样的。

m:默认的正则开始"^"和结束"$"只是对于正则字符串如果在修饰符中加上"m",那么开始和结束将会指字符串的每一行:每一行的开头就是"^",结尾就是"$"。

s:如果在修饰符中加入"s",那么默认的"."代表除了换行符以外的任何字符将会变成任意字符,也就是包括换行符!

x:如果加上该修饰符,表达式中的空白字符将会被忽略,除非它已经被转义。

e:本修饰符仅仅对于replacement有用,代表在replacement中作为PHP代码。

A:如果使用这个修饰符,那么表达式必须是匹配的字符串中的开头部分。比如说"/a/A"匹配"abcd"。

E:与"m"相反,如果使用这个修饰符,那么"$"将匹配绝对字符串的结尾,而不是换行符前面,默认就打开了这个模式。

U:和问号的作用差不多,用于设置"贪婪模式"。

 

7 PCRE相关的正则表达式函数:

PHP的Perl兼容正则表达式提供的多个函数,分为模式匹配,替换和匹配数目等等:

1、preg_match :

函数格式:intpreg_match(string pattern, string subject, array [matches]);

这个函数会在string中使用pattern表达式来匹配,如果给定了[regs],就会将string记录到[regs][0]中,[regs][1]代表使用括号"()"记录下来的第一个字符串,[regs][2]代表记录下来的第二个字符串,以此类推。preg如果在string中找到了匹配的pattern,就会返回"true",否则返回"false"。

 

2、preg_replace :

函数格式:mixedpreg_replace(mixed pattern, mixed replacement, mixed subject);

这个函数会使用将string中符合表达式pattern的字符串全部替换为表达式replacement。如果replacement中需要包含pattern的部分字符,则可以使用"()"来记录,在replacement中只是需要用"\\1"来读取。

 

3、preg_split :

函数格式:arraypreg_split(string pattern, string subject, int [limit]);

这个函数和函数split一样,区别仅在与split可以使用简单正则表达式来分割匹配的字符串,而preg_split使用完全的Perl兼容正则表达式。第三个参数limit代表允许返回多少个符合条件的值。

 

4、preg_grep :

函数格式:arraypreg_grep(string patern , array input);

这个函数和preg_match功能基本上,不过preg_grep可以将给定的数组input中的所有元素匹配,返回一个新的数组。

 

下面举一个例子,比如我们要检查Email地址的格式是否正确:

 

<?php

function emailIsRight($email) {

if(preg_match("^[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3}$",$email)){

return 1;

}

return 0;

}

if(emailIsRight(\'y10k@963.net\')) echo \'正确<br>\';

if(!emailIsRight(\'y10k@fffff\')) echo \'不正确<br>\';

?>

 

上面的程序会输出"正确<br>不正确"。

8.PHP中的Perl兼容正则表达式和Perl/Ereg正则表达式的区别:

虽然叫做“Perl兼容正则表达式”,但是和Perl的正则表达式相比,PHP的还是由一些不同,比如修饰符“G”在Perl里面代表全部匹配,但是在PHP中没有加入对这个修饰符的支持。

还有就是和ereg系列函数的区别,ereg也是PHP中提供的正则表达式函数,不过和preg相比,要弱上很多。

 

1、ereg里面是不需要也不能使用分隔符和修饰符的,所以ereg的功能比preg要弱上不少。

2、关于".":点在正则里面一般是除了换行符以外的全部字符,但是在ereg里面的"."是任意字符,即包括换行符!如果在preg里面希望"."能够包括换行符,可以在修饰符中加上"s"。

3、ereg默认使用贪婪模式,并且不能修改,这个给很多替换和匹配带来麻烦。

4、速度:这个或许是很多人关心的问题,会不会preg功能强大是以速度来换取的?不用担心,preg的速度要远远比ereg快,笔者做了一个程序测试:

 

time test:

 

PHP代码:

<?php

echo "Preg_replace used time:";

$start = time();

for($i=1;$i<=100000;$i++) {

$str ="ssssssssssssssssssssssssssss";

preg_replace("/s/","",$str);

}

$ended = time()-$start;

echo $ended;

echo "

ereg_replace used time:";

$start = time();

for($i=1;$i<=100000;$i++) {

$str ="ssssssssssssssssssssssssssss";

ereg_replace("s","",$str);

}

$ended = time()-$start;

echo $ended;

echo "

str_replace used time:";

$start = time();

for($i=1;$i<=100000;$i++) {

$str ="sssssssssssssssssssssssssssss";

str_replace("s","",$str);

}

$ended = time()-$start;

echo $ended;

?>

结果:

Preg_replace used time:5

ereg_replace used time:15

str_replace used time:2

 

str_replace因为不需要匹配所以速度非常快,而preg_replace的速度比ereg_replace要快上不少。

原创粉丝点击