php的正则处理函数总结分析


Posted in PHP onJune 20, 2008

preg_grep
(PHP 4, PHP 5)

preg_grep --   返回与模式匹配的数组单元 
说明
array preg_grep ( string pattern, array input [, int flags] )

preg_grep() 返回一个数组,其中包括了 input 数组中与给定的 pattern 模式相匹配的单元。 

flags 可以是以下标记: 

PREG_GREP_INVERT 
如果传递入此标记,preg_grep() 会返回输入数组中不匹配给定 pattern 的单元。本标记自 PHP 4.2.0 起可用。 

自 PHP 4.0.4 起,preg_grep() 返回的结果使用从输入数组来的键名进行索引。如果不希望这样的结果,用 array_values() 对 preg_grep() 返回的结果重新索引。 

上面是手册上对preg_grep()的说明。首先这是perl兼容的正则函数,所以我猜想preg_grep的意思是p(perl)reg(regular)_grep,其特点是可做用于数组,通过自己扩展,可用做多维数组中的正则匹配,并且可以通过flags参数返回匹配或者非匹配数组。其效率比用foreach(...){if...}结构快很多(未验证),而且可匹配复杂模式。在搜索、分检等应用中用途不小。

例:

<?
$arr = array('abc'=>12.213,'bb'=>12345,'ba'=>23.2321,34.3,'23'=>'3.3','23434'=>'bbb');

// 返回所有含有浮点数的数组元素。
$fl_array = preg_grep ("/^(\d+)?\.\d+$/", $arr);
print_r($fl_array);

?>

preg_match
(PHP 3 >= 3.0.9, PHP 4, PHP 5)

preg_match -- 进行正则表达式匹配
说明
int preg_match ( string pattern, string subject [, array matches [, int flags]] )

在 subject 字符串中搜索与 pattern 给出的正则表达式相匹配的内容。 

如果提供了 matches,则其会被搜索的结果所填充。$matches[0] 将包含与整个模式匹配的文本,$matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推。 

flags 可以是下列标记: 

PREG_OFFSET_CAPTURE 
如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其偏移量。本标记自 PHP 4.3.0 起可用。 

flags 参数自 PHP 4.3.0 起可用。 

preg_match() 返回 pattern 所匹配的次数。要么是 0 次(没有匹配)或 1 次,因为 preg_match() 在第一次匹配之后将停止搜索。preg_match_all() 则相反,会一直搜索到 subject 的结尾处。如果出错 preg_match() 返回 FALSE。 

提示: 如果只想查看一个字符串是否包含在另一个字符串中,不要用 preg_match()。可以用 strpos() 或 strstr() 替代,要快得多。 

上面是手册里对preg_match()的说明,我认为这个函数的功用在于他可做来做验证,也就是某字符串是否符合某特定要求。其局限是上面所说的要么匹配0次,要么1次。并且返回值是匹配次数。当需要全匹配时可使用preg_match_all().另外值得一提的是$matches数组的作用,可做自模式的返回值,有时很有用。

例:

<?

if (preg_match ("/(\bweb\b)\s(\d)/i", "PHP is the web 45 scripting web 34 language of choice.",$match)) {
     print "A match was found.";
print_r($match);
} else {
     print "A match was not found.";
}

?>

<?php
// 从 URL 中取得主机名
preg_match("/^(http:\/\/)?([^\/]+)/i",
     "http://www.php.net/index.html", $matches);
$host = $matches[2];

// 从主机名中取得后面两段
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
echo "domain name is: {$matches[0]}\n";
?> 

preg_match_all
(PHP 3 >= 3.0.9, PHP 4, PHP 5)

preg_match_all -- 进行全局正则表达式匹配

手册上该函数的解释非常明确,就不多做说明了。
说明
int preg_match_all ( string pattern, string subject, array matches [, int flags] )

在 subject 中搜索所有与 pattern 给出的正则表达式匹配的内容并将结果以 flags 指定的顺序放到 matches 中。 

搜索到第一个匹配项之后,接下来的搜索从上一个匹配项末尾开始。 

flags 可以是下列标记的组合(注意把 PREG_PATTERN_ORDER 和 PREG_SET_ORDER 合起来用没有意义): 

PREG_PATTERN_ORDER 
对结果排序使 $matches[0] 为全部模式匹配的数组,$matches[1] 为第一个括号中的子模式所匹配的字符串组成的数组,以此类推。 

<?php
preg_match_all ("|<[^>]+>(.*)</[^>]+>|U",
     "<b>example: </b><div align=left>this is a test</div>",
     $out, PREG_PATTERN_ORDER);
print $out[0][0].", ".$out[0][1]."\n";
print $out[1][0].", ".$out[1][1]."\n";
?>  

本例将输出: 

<b>example: </b>, <div align=left>this is a test</div>
example: , this is a test

因此,$out[0] 包含匹配整个模式的字符串,$out[1] 包含一对 HTML 标记之间的字符串。 

PREG_SET_ORDER 
对结果排序使 $matches[0] 为第一组匹配项的数组,$matches[1] 为第二组匹配项的数组,以此类推。 

<?php
preg_match_all ("|<[^>]+>(.*)</[^>]+>|U",
     "<b>example: </b><div align=left>this is a test</div>",
     $out, PREG_SET_ORDER);
print $out[0][0].", ".$out[0][1]."\n";
print $out[1][0].", ".$out[1][1]."\n";
?>  

本例将输出: 

<b>example: </b>, example:
<div align=left>this is a test</div>, this is a test

本例中,$matches[0] 是第一组匹配结果,$matches[0][0] 包含匹配整个模式的文本,$matches[0][1] 包含匹配第一个子模式的文本,以此类推。同样,$matches[1] 是第二组匹配结果,等等。 

PREG_OFFSET_CAPTURE 
如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其在 subject 中的偏移量。本标记自 PHP 4.3.0 起可用。 

如果没有给出标记,则假定为 PREG_PATTERN_ORDER。 

返回整个模式匹配的次数(可能为零),如果出错返回 FALSE。 

例子 1. 从某文本中取得所有的电话号码

<?php
preg_match_all ("/\(?   (\d{3})?   \)?   (?(1)   [\-\s] ) \d{3}-\d{4}/x",
                 "Call 555-1212 or 1-800-555-1212", $phones);
?>  

例子 2. 搜索匹配的 HTML 标记(greedy)

<?php
// \\2 是一个逆向引用的例子,其在 PCRE 中的含义是
// 必须匹配正则表达式本身中第二组括号内的内容,本例中
// 就是 ([\w]+)。因为字符串在双引号中,所以需要
// 多加一个反斜线。
$html = "<b>bold text</b><a href=howdy.html>click me</a>";

preg_match_all ("/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/", $html, $matches);

for ($i=0; $i< count($matches[0]); $i++) {
   echo "matched: ".$matches[0][$i]."\n";
   echo "part 1: ".$matches[1][$i]."\n";
   echo "part 2: ".$matches[3][$i]."\n";
   echo "part 3: ".$matches[4][$i]."\n\n";
}
?>  

preg_quote
(PHP 3 >= 3.0.9, PHP 4, PHP 5)

preg_quote -- 转义正则表达式字符
说明
string preg_quote ( string str [, string delimiter] )

preg_quote() 以 str 为参数并给其中每个属于正则表达式语法的字符前面加上一个反斜线。如果你需要以动态生成的字符串作为模式去匹配则可以用此函数转义其中可能包含的特殊字符。 

如果提供了可选参数 delimiter,该字符也将被转义。可以用来转义 PCRE 函数所需要的定界符,最常用的定界符是斜线 /。 

正则表达式的特殊字符包括:. \ + * ? [ ^ ] $ ( ) { } = ! < > | :。 

注: 本函数可安全用于二进制对象。

上面是手册上的解释,也很明白,不多说了,另外手册上还有一注释就是该函数可安全用于二进制对象,这点很有用。

例: 例子 1. preg_quote() 例子

<?php
$keywords = '$40 for a g3/400';
$keywords = preg_quote($keywords, '/');
echo $keywords; // returns \$40 for a g3\/400
?>  

例子 2. 给某文本中的一个单词加上斜体标记

<?php
// 本例中,preg_quote($word) 用来使星号不在正则表达式中
// 具有特殊含义。

$textbody = "This book is *very* difficult to find.";
$word = "*very*";
$textbody = preg_replace ("/".preg_quote($word)."/",
                           "<i>".$word."</i>",
                           $textbody);
?>  

接下来就是应用超灵活、、功能超强大、使用超广泛的preg_replace函数。

preg_replace
(PHP 3 >= 3.0.9, PHP 4, PHP 5)

preg_replace -- 执行正则表达式的搜索和替换
说明
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit] )

在 subject 中搜索 pattern 模式的匹配项并替换为 replacement。如果指定了 limit,则仅替换 limit 个匹配,如果省略 limit 或者其值为 -1,则所有的匹配项都会被替换。 

replacement 可以包含 \\n 形式或(自 PHP 4.0.4 起)$n 形式的逆向引用,首选使用后者。每个此种引用将被替换为与第 n 个被捕获的括号内的子模式所匹配的文本。n 可以从 0 到 99,其中 \\0 或 $0 指的是被整个模式所匹配的文本。对左圆括号从左到右计数(从 1 开始)以取得子模式的数目。 

对替换模式在一个逆向引用后面紧接着一个数字时(即:紧接在一个匹配的模式后面的数字),不能使用熟悉的 \\1 符号来表示逆向引用。举例说 \\11,将会使 preg_replace() 搞不清楚是想要一个 \\1 的逆向引用后面跟着一个数字 1 还是一个 \\11 的逆向引用。本例中的解决方法是使用 \${1}1。这会形成一个隔离的 $1 逆向引用,而使另一个 1 只是单纯的文字。 

如果搜索到匹配项,则会返回被替换后的 subject,否则返回原来不变的 subject。 

preg_replace() 的每个参数(除了 limit)都可以是一个数组。如果 pattern 和 replacement 都是数组,将以其键名在数组中出现的顺序来进行处理。这不一定和索引的数字顺序相同。如果使用索引来标识哪个 pattern 将被哪个 replacement 来替换,应该在调用 preg_replace() 之前用 ksort() 对数组进行排序。 

如果 subject 是个数组,则会对 subject 中的每个项目执行搜索和替换,并返回一个数组。 

如果 pattern 和 replacement 都是数组,则 preg_replace() 会依次从中分别取出值来对 subject 进行搜索和替换。如果 replacement 中的值比 pattern 中的少,则用空字符串作为余下的替换值。如果 pattern 是数组而 replacement 是字符串,则对 pattern 中的每个值都用此字符串作为替换值。反过来则没有意义了。 

/e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。 

注: limit 参数是 PHP 4.0.1pl2 之后加入的。 

我认为其强大之处就是他不但可以处理字符串,而且可以处理数组,并且他的逆向引用功能非常灵活。基本上他可以满足普通用户的大部分需求,如果他不能胜任,那么我们还有preg_replace_callback()函数,可以自定义回调函数,满足你的高级要求。如设计过滤器等。

preg_replace_callback
(PHP 4 >= 4.0.5, PHP 5)

preg_replace_callback -- 用回调函数执行正则表达式的搜索和替换
说明
mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] )

本函数的行为几乎和 preg_replace() 一样,除了不是提供一个 replacement 参数,而是指定一个 callback 函数。该函数将以目标字符串中的匹配数组作为输入参数,并返回用于替换的字符串。 

例子 1. preg_replace_callback() 例子

<?php
   // 此文本是用于 2002 年的,
   // 现在想使其能用于 2003 年
   $text = "April fools day is 04/01/2002\n";
   $text.= "Last christmas was 12/24/2001\n";

   // 回调函数
   function next_year($matches) {
     // 通常:$matches[0] 是完整的匹配项
     // $matches[1] 是第一个括号中的子模式的匹配项
     // 以此类推
     return $matches[1].($matches[2]+1);
   }

   echo preg_replace_callback(
               "|(\d{2}/\d{2}/)(\d{4})|",
               "next_year",
               $text);

   // 结果为:
   // April fools day is 04/01/2003
   // Last christmas was 12/24/2002
?>  

You'll often need the callback function for a preg_replace_callback() in just one place. In this case you can use create_function() to declare an anonymous function as callback within the call to preg_replace_callback(). By doing it this way you have all information for the call in one place and do not clutter the function namespace with a callback functions name not used anywhere else. 

对于使用preg_replace_callback()函数的朋友来说,你应该回需要callback函数(否则用他干嘛,直接用preg_replace不是更好),不过也经常只是用一处。既然这样你可以用create_function()来声明一个匿名函数作为preg_replace_callback()的回调函数。这样,我们即满足了声明信息的需要,有不致因这个不会再用到的函数名而混乱。

例子 2. preg_replace_callback() 和 create_function()

<?php
   /* 一个 UNIX 风格的命令行过滤器,将每个段落开头的
   * 大写字母转换成小写字母 */

   $fp = fopen("php://stdin", "r") or die("can't read stdin");
   while (!feof($fp)) {
       $line = fgets($fp);
       $line = preg_replace_callback(
           '|<p>\s*\w|',
           create_function(
               // 这里使用单引号很关键,
               // 否则就把所有的 $ 换成 \$
               '$matches',
               'return strtolower($matches[0]);'
           ),
           $line
       );
       echo $line;
   }
   fclose($fp);
?>  

最后是

preg_split
(PHP 3 >= 3.0.9, PHP 4, PHP 5)

preg_split -- 用正则表达式分割字符串
不再赘述。
说明
array preg_split ( string pattern, string subject [, int limit [, int flags]] )

返回一个数组,包含 subject 中沿着与 pattern 匹配的边界所分割的子串。 

如果指定了 limit,则最多返回 limit 个子串,如果 limit 是 -1,则意味着没有限制,可以用来继续指定可选参数 flags。 

flags 可以是下列标记的任意组合(用按位或运算符 | 组合): 

PREG_SPLIT_NO_EMPTY 
如果设定了本标记,则 preg_split() 只返回非空的成分。 

PREG_SPLIT_DELIM_CAPTURE 
如果设定了本标记,定界符模式中的括号表达式也会被捕获并返回。本标记添加于 PHP 4.0.5。 

PREG_SPLIT_OFFSET_CAPTURE 
如果设定了本标记,如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其在 subject 中的偏移量。本标记自 PHP 4.3.0 起可用。 

提示: 如果不需要正则表达式的功能,可以选择使用更快(也更简单)的替代函数如 explode() 或 str_split()。  

PHP 相关文章推荐
php去除重复字的实现代码
Sep 16 PHP
PHP+Mysql日期时间如何转换(UNIX时间戳和格式化日期)
Jul 15 PHP
PHP fopen 读取带中文URL地址的一点见解
Sep 25 PHP
解析使用substr截取UTF-8中文字符串出现乱码的问题
Jun 20 PHP
smarty实现多级分类的方法
Dec 05 PHP
PHP面向对象之后期静态绑定功能介绍
May 18 PHP
10款实用的PHP开源工具
Oct 23 PHP
PHP实现图片上传并压缩
Dec 22 PHP
php利用gd库为图片添加水印
Nov 09 PHP
php时间戳转换代码详解
Aug 04 PHP
PHP实现倒计时功能
Nov 16 PHP
PHP 实现链式操作
Mar 09 PHP
PHP伪静态页面函数附使用方法
Jun 20 #PHP
PHP伪静态写法附代码
Jun 20 #PHP
用PHP伪造referer突破网盘禁止外连的代码
Jun 15 #PHP
php学习 字符串课件
Jun 15 #PHP
php学习 函数 课件
Jun 15 #PHP
PHP学习 运算符与运算符优先级
Jun 15 #PHP
坏狼php学习 计数器实例代码
Jun 15 #PHP
You might like
PHP怎样调用MSSQL的存储过程
2006/10/09 PHP
(仅IE下有效)关于checkbox 三态
2007/05/12 Javascript
高性能Javascript笔记 数据的存储与访问性能优化
2012/08/02 Javascript
Json实现异步请求提交评论无需跳转其他页面
2014/10/11 Javascript
5个JavaScript经典面试题
2014/10/13 Javascript
jquery实现从数组移除指定的值
2015/06/24 Javascript
基于jquery实现全屏滚动效果
2015/11/26 Javascript
jquery实现具有嵌套功能的选项卡
2016/02/12 Javascript
JS定时器实现数值从0到10来回变化
2016/12/09 Javascript
详解使用grunt完成requirejs的合并压缩和js文件的版本控制
2017/03/02 Javascript
Extjs 中的 Treepanel 实现菜单级联选中效果及实例代码
2017/08/22 Javascript
Vue中computed与methods的区别详解
2018/03/24 Javascript
vue 监听某个div垂直滚动条下拉到底部的方法
2018/09/15 Javascript
vue 实现在同一界面实现组件的动态添加和删除功能
2020/06/16 Javascript
在Vue 中获取下拉框的文本及选项值操作
2020/08/13 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
python读取和保存图片5种方法对比
2018/09/12 Python
python 实现数字字符串左侧补零的方法
2018/12/04 Python
浅谈python编译pyc工程--导包问题解决
2019/03/20 Python
python中比较两个列表的实例方法
2019/07/04 Python
python绘制雪景图
2019/12/16 Python
python 实现保存最新的三份文件,其余的都删掉
2019/12/22 Python
pytorch之ImageFolder使用详解
2020/01/06 Python
解决Python图形界面中设置尺寸的问题
2020/03/05 Python
Python面向对象程序设计之静态方法、类方法、属性方法原理与用法分析
2020/03/23 Python
HTML5 Canvas绘制五星红旗
2016/05/04 HTML / CSS
JD Sports法国:英国篮球和运动时尚的领导者
2017/09/28 全球购物
Android面试题及答案
2015/09/04 面试题
Ruby如何定义一个类
2012/10/08 面试题
应届毕业生应聘自荐信
2013/12/07 职场文书
售后客服工作职责
2014/06/16 职场文书
汽车运用工程专业求职信
2014/06/18 职场文书
开发房地产协议书
2014/09/14 职场文书
实习单位指导教师评语
2014/12/30 职场文书
Python爬虫实战之爬取京东商品数据并实实现数据可视化
2021/06/07 Python
CentOS MySql8 远程连接实战
2022/04/19 MySQL