网站开发日志

2008年10月4日星期六

分享家:Addthis中国

PHP Regular Expressions

我在上一篇文章:Perl 正则表达式 中,对Perl Regrex 做了详细的介绍。在使用PHP的正则表达式时,我一直都是运用Perl的正则表达式思想来实现的,因为两者在字符串的匹配规则是相通的。在这篇文章里,我主要介绍如何把Perl的正则表达式运用于PHP中。

Perl的正则表达式表达式书写非常简洁,而PHP通过函数(function)来实现的。先看个例子:

#Perl
$string = "Clinton是美国第42届总统";
if($string =~ m/^(Clinton|Bush|Reagan).*(\d{2})/i)
  {print "$1\t$2\n"};
#在Perl里我们用$1表示第一给匹配组'()'里的内容.$2表示第二个匹配组里的内容。
#显然打印结果是: Clinton   42
//PHP
$string = "Clinton 是美国第42届总统";
if(preg_match("/^(Clinton|Bush|Reagan).*(\d{2})/", $string, $matches))
   print $matches[1]\t$matches[2]\n";
//首先PHP要用函数preg_match($pattern,$string,$matches)来实现匹配判断
//其次,匹配结果被放在数组$matches里。
//最后,如果匹配成立,数组的第一个值是整个匹配字符串,第二个值才是第一匹配组里的内容。
//所以,$matches[1]匹配'Clinton',$matches[2]匹配'42'

如果你读懂了上面的例子,你大概已经知道如何使用PHP的函数,preg_match()。preg_match这个函数主要接受三个变量输入:$pattern(匹配式样)、$string (要进行匹配的字符串)、$matches(匹配结果数组)。第一个变量参数是难点,可以完全应用Perl的正则表达式。另外一个难点,是对匹配内容的选择,在perl里用$1,$2,等等,在这里用数组$matches,$matches[1]相当于$1。

下面这里例子介绍如何用preg_match()来验证邮箱。我曾介绍过Javascript验证邮箱,原理差不多。

<?php
    $okay = preg_match(
      '/^[A-z0-9_\-]+[@][A-z0-9_\-]+([.][A-z0-9_\-]+)+[.][A-z]{2,4}$/', 
      $email
    );
    if ($okay) {
      echo "E-mail is validated";
    } else {
      echo "E-mail is incorrect";
    }
?> 
//因为我只要知道输入的email是否匹配合法的表达式,也就是不保存匹配结果,
//所以在调用preg_match()的时候只需要两个变量输入,$pattern和$email
//这里pattern = /^[A-z0-9_\-]+[@][A-z0-9_\-]+([.][A-z0-9_\-]+)+[.][A-z]{2,4}$/
//我们可以把pattern分为6段来分析:
//1. ^[A-z0-9_\-]+:以任意一个或者多个字母或者数字或者下划线或者连字号开头
//2. [@]中间是@
//3. [A-z0-9_\-]+: @后面跟着一个或者多个字母或者数字或者下划线或者连字号
//4. ([.][A-z0-9_\-]+)+: 之后跟着一个或者多个(.字符或者字符串)
//5. [.]: 之后跟一个点
//6. [A-z]{2,4}$: 最后跟2-4个英文字母。(比如说:com, net, edu, cn, 等等)

第三个例子是对百度知道一个网页的问题回答:

$str = "任意字符串1<aaa 任意字符串2>任意字符串3<aaa 任意字符串4>任意字符串5</aaa>";
//我想取出:
//$arr1 = 任意字符串1
//$arr2 = 任意字符串2
//$arr3 = 剩下的东东(任意字符串3<aaa 任意字符串4>任意字符串5</aaa>
//答案:
preg_match ('/^(.*?)<aaa\s(.*?)>(.*)$/', $str, $out);
echo $out[1] . "\n";
echo $out[2] . "\n";
echo $out[3] . "\n";
//注意:这里用到非贪婪匹配
//'^(.*?)<aaa', 匹配组匹配其实字符到碰到第一个'<aaa'前的所有字符
//如果我们用'^(.*)<aaa', 那么将贪婪匹配到最后一个'<aaa'前的所有字符

补充(11/6/08) 需要匹配多行的字符串,使用“smi”后缀修饰。例如:

$a = '<{LIST(10011002,10,0,0)}>
<tr>
<td width="100"> </td>
<td> </td>
<tr>
<{/LIST}> ';
if (preg_match("/<{[^}]+}\>(.+)\<{[^}]+}>/smi", $a)){
   print "yes";
}
补充(11/10/08) "\b"表示单词的分界线。比如说,"\bweb\b" 匹配"web", 但是不匹配"website"。

标签:

相关文章:

0 条评论:

发表评论

指向此帖子的链接: