PHP中的正则表达式函数
6.3 PHP中的正则表达式函数
在PHP中有两套 正则表达式函数库。一套是由PCRE(Perl Compatible Regular Expression)库提供的。PCRE库使用和Perl相同的语法规则实现了正则表达式的模式匹配,其使用以“preg_”为前缀命名的函数。另一套 是由POSIX(Portable Operation System interface)扩展库提供的。POSIX扩展的正则表达式由POSIX 1003.2定义,一般使用以“ereg_”为前缀命名的函数。
两套函数库的功能相似,执行效率稍有不同。一般而言,实现相同的功能,使用PCRE库的效率略占优势。下面详细介绍其使用方法。
6.3.1 正则表达式的匹配
1.preg_match()
函数原型:int preg_match (string $pattern, string $content [, array $matches])
preg_match ()函数在$content字符串中搜索与$pattern给出的正则表达式相匹配的内容。如果提供了$matches,则将匹配结果放入其 中。$matches[0]将包含与整个模式匹配的文本,$matches[1]将包含第一个捕获的与括号中的模式单元所匹配的内容,以此类推。该函数只 作一次匹配,最终返回0或1的匹配结果数。代码6.1给出preg_match()函数的一段代码示例。
代码6.1 日期时间的匹配
01 |
<?php |
02 |
//需要匹配的字符串。date函数返回当前时间 |
03 |
$content = "Current date and time is " . date ( "Y-m-d h:i a" ). ", we are learning PHP together." ; |
04 |
//使用通常的方法匹配时间 |
05 |
if (preg_match ( "/d{4}-d{2}-d{2} d{2}:d{2} [ap]m/" , $content , $m )) |
06 |
{ |
07 |
echo "匹配的时间是:" . $m [0]. " " ; |
08 |
} |
09 |
//由于时间的模式明显,也可以简单的匹配 |
10 |
if (preg_match ( "/([d-]{10}) ([d:]{5} [ap]m)/" , $content , $m )) |
11 |
{ |
12 |
echo "当前日期是:" . $m [1]. " " ; |
13 |
echo "当前时间是:" . $m [2]. " " ; |
14 |
} |
15 |
?> |
这是一个简单动态文本串匹配实例。假设当前系统时间是“2006年8月17日13点25分”,将输出如下的内容。
匹配的时间是:2006-08-17 01:25 pm
当前日期是:2006-08-17
当前时间是:01:25 pm
2.ereg()和eregi()
ereg() 是POSIX扩展库中正则表达式的匹配函数。eregi()是ereg()函数的忽略大小写的版本。二者与preg_match的功能类似,但函数返回的 是一个布尔值,表明匹配成功与否。需要说明的是,POSIX扩展库函数的第一个参数接受的是正则表达式字符串,即不需要使用分界符。例如,代码6.2是一 个关于文件名安全检验的方法。
代码6.2 文件名的安全检验
01 |
<?php |
02 |
$username = $_SERVER [ 'REMOTE_USER' ]; |
03 |
$filename = $_GET [ 'file' ]; |
04 |
//对文件名进行过滤,以保证系统安全 |
05 |
if (! ereg ( '^[^./][^/]*$' , $userfile )) |
06 |
{ |
07 |
die ( '这不是一个非法的文件名!' ); |
08 |
} |
09 |
//对用户名进行过滤 |
10 |
if (! ereg ( '^[^./][^/]*$' , $username )) |
11 |
{ |
12 |
die ( '这不是一个无效的用户名' ); |
13 |
} |
14 |
|
15 |
//通过安全过滤,拼合文件路径 |
16 |
$thefile = "/home/$username/$filename" ; |
17 |
?> |
通常情况下,使用与Perl兼容的正则表达式匹配函数perg_match(),将比使用ereg()或eregi()的速度更快。如果只是查找一个字符串中是否包含某个子字符串,建议使用strstr()或strpos()函数。
3.preg_grep()
函数原型:array preg_grep (string $pattern, array $input)
preg_grep()函数返回一个数组,其中包括了$input数组中与给定的$pattern模式相匹配的单元。对于输入数组$input中的每个元素,preg_grep()也只进行一次匹配。代码6.3给出的示例简单地说明了preg_grep()函数的使用。
代码6.3 数组查询匹配
01 |
<strong><font size= "4" ><?php |
02 |
$subjects = array ( |
03 |
"Mechanical Engineering" , "Medicine" , |
04 |
"Social Science" , "Agriculture" , |
05 |
"Commercial Science" , "Politics" |
06 |
); |
07 |
|
08 |
//匹配所有仅由有一个单词组成的科目名 |
09 |
$alonewords = preg_grep( "/^[a-z]*$/i" , $subjects ); |
10 |
?> |
11 |
</font></strong> |
6.3.2 进行全局正则表达式匹配
1.preg_match_all()
与 preg_match()函数类似。如果使用了第三个参数,将把所有可能的匹配结果放入。本函数返回整个模式匹配的次数(可能为0),如果出错返回 False。下面是一个将文本中的URL链接地址转换为HTML代码的示例。代码6.4是preg_match_all()函数的使用范例。
代码6.4 将文本中的链接地址转成HTML
01 |
<strong><font size= "3" ><?php |
02 |
//功能:将文本中的链接地址转成HTML |
03 |
//输入:字符串 |
04 |
//输出:字符串 |
05 |
function url2html( $text ) |
06 |
{ |
07 |
//匹配一个URL,直到出现空白为止 |
08 |
preg_match_all( "/http://?[^s] /i" , $text , $links ); |
09 |
//设置页面显示URL地址的长度 |
10 |
$max_size = 40; |
11 |
foreach ( $links [0] as $link_url ) |
12 |
{ |
13 |
//计算URL的长度。如果超过$max_size的设置,则缩短。 |
14 |
$len = strlen ( $link_url ); |
15 |
if ( $len > $max_size ) |
16 |
{ |
17 |
$link_text = substr ( $link_url , 0, $max_size ). "..." ; |
18 |
} else { |
19 |
$link_text = $link_url ; |
20 |
} |
21 |
//生成HTML文字 |
22 |
$text = str_replace ( $link_url , "<a href='$link_url'>$link_text</a>" , $text ); |
23 |
} |
24 |
return $text ; |
25 |
} |
26 |
|
27 |
//运行实例 |
28 |
$str = “这是一个包含多个URL链接地址的多行文字。欢迎访问http: //www.taoboor.com”; |
29 |
print url2html( $str ); |
30 |
/*输出结果 |
31 |
这是一个包含多个URL链接地址的多行文字。欢迎访问<a href='http://www.taoboor.com'> |
33 |
*/ |
34 |
?> |
35 |
</font></strong> |
2.多行匹配
仅仅使用POSIX下的正则表式函数,很难进行复杂的匹配操作。例如,对整个文件(尤其是多行文本)进行匹配查找。使用ereg()对此进行操作的一个方法是分行处理。代码6.5的示例演示了ereg()如何将INI文件的参数赋值到数组之中。
代码6.5 文件内容的多行匹配
01 |
<?php |
02 |
$rows = file( 'php.ini' ); //将php.ini文件读到数组中 |
03 |
//循环遍历 |
04 |
foreach ( $rows as $line ) |
05 |
{ |
06 |
If(trim( $line )) |
07 |
{ |
08 |
//将匹配成功的参数写入数组中 |
09 |
if ( eregi ( "^([a-z0-9_.]*) *=(.*)" , $line , $matches )) |
10 |
{ |
11 |
$options [ $matches [1]] = trim( $matches [2]); |
12 |
} |
13 |
unset( $matches ); |
14 |
} |
15 |
} |
16 |
//输出参数结果 |
17 |
print_r( $options ); |
18 |
?> |
提示 |
这里只是为了方便说明问题。解析一个*.ini文件,最佳方法是使用函数parse_ini_file()。该函数直接将*.ini文件解析到一个大数组中。 |
PHP中的正则表达式函数
www.firnow.com 时间 : 2010-10-29 作者:佚名 编辑:fnw 点击: 1328 [ 评论 ]
6.3.3 正则表达式的替换
1.ereg_replace()和eregi_replace()
函数原型:
1 |
string ereg_replace (string $pattern , string $replacement , string $string ) |
2 |
string eregi_replace (string $pattern , string $replacement , string $string ) |
ereg_replace()在$string中搜索模式字符串$pattern,并将所匹配结果替换为$replacement。 当$pattern中包含模式单元(或子模式)时,$replacement中形如“1”或“$1”的位置将依次被这些子模式所匹配的内容替换。而“ �”或“$0”是指整个的匹配字符串的内容。需要注意的是,在双引号中反斜线作为转义符使用,所以必须使用“�”,“1”的形式。
eregi_replace()和ereg_replace()的功能一致,只是前者忽略大小写。代码6.6是本函数的应用实例,这段代码演示了如何对程序源代码做简单的清理工作。
代码6.6 源代码的清理
01 |
<strong><font size= "3" ><?php |
02 |
$lines = file( 'source.php' ); //将文件读入数组中 |
03 |
for ( $i =0; $i < count ( $lines ); $i ) |
04 |
{ |
05 |
//将行末以“”或“#”开头的注释去掉 |
06 |
$lines [ $i ] = eregi_replace ( "(//|#).*$" , "" , $lines [ $i ]); |
07 |
//将行末的空白消除 |
08 |
$lines [ $i ] = eregi_replace ( "[ vf]*$" , " " , $lines [ $i ]); |
09 |
} |
10 |
//整理后输出到页面 |
11 |
echo htmlspecialchars(join( "" , $lines )); |
12 |
?> |
13 |
</font></strong> |
2.preg_replace()
函数原型:mixed preg_replace (mixed $pattern, mixed $replacement, mixed $subject [, int $limit])
preg_replace较ereg_replace的功能更加强大。其前三个参数均可以使用数组;第四个参数$limit可以设置替换的次数,默认为全部替换。代码6.7是一个数组替换的应用实例。
代码6.7 数组替换
01 |
<?php |
02 |
//字符串 |
03 |
$string = "Name: {Name}<br> Email: {Email}<br> Address: {Address}<br> " ; |
04 |
//模式 |
05 |
$patterns = array ( |
06 |
"/{Address}/" , |
07 |
"/{Name}/" , |
08 |
"/{Email}/" |
09 |
); |
10 |
//替换字串 |
11 |
$replacements = array ( |
12 |
"No.5, Wilson St., New York, U.S.A" , |
13 |
"Thomas Ching" , |
14 |
"tom@emailaddress.com" , |
15 |
); |
16 |
//输出模式替换结果 |
17 |
print preg_replace( $patterns , $replacements , $string ); |
18 |
?> |
输出结果如下。
Name: Thomas Ching",
Email: tom@emailaddress.com
Address: No.5, Wilson St., New York, U.S.A
在preg_replace的正则表达式中可以使用模式修正符“e”。其作用是将匹配结果用作表达式,并且可以进行重新运算。