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将数据库导出成excel的方法
May 07 PHP
PHP mb_convert_encoding文字编码的转换函数介绍
Nov 10 PHP
win7下memCache的安装过程(具体操作步骤)
Jun 28 PHP
php上传文件中文文件名乱码的解决方法
Nov 01 PHP
ThinkPHP自动填充实现无限级分类的方法
Aug 22 PHP
一个图片地址分解程序(用于PHP小偷程序)
Aug 23 PHP
php抓取并保存网站图片的实现代码
Oct 28 PHP
PHP基于PDO实现的SQLite操作类【包含增删改查及事务等操作】
Jun 21 PHP
Yii2.0实现的批量更新及批量插入功能示例
Jan 29 PHP
YII框架页面缓存操作示例
Apr 29 PHP
php设计模式之观察者模式定义与用法经典示例
Sep 19 PHP
PHP7 其他修改
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
星际争霸秘籍
2020/03/04 星际争霸
3
2006/10/09 PHP
用libTemplate实现静态网页的生成
2006/10/09 PHP
URL Rewrite的设置方法
2007/01/02 PHP
php比较相似字符串的方法
2015/06/05 PHP
如何使用PHP Embed SAPI实现Opcodes查看器
2015/11/10 PHP
详解php用static方法的原因
2018/09/12 PHP
php实现的简单多进程服务器类完整示例
2020/02/01 PHP
js split 的用法和定义 js split分割字符串成数组的实例代码
2012/05/13 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
2013/04/12 Javascript
jQuery中removeProp()方法用法实例
2015/01/05 Javascript
JS实现的仿东京商城菜单、仿Win右键菜单及仿淘宝TAB特效合集
2015/09/28 Javascript
跟我学习javascript的var预解析与函数声明提升
2015/11/16 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
2015/11/29 Javascript
jquery Deferred 快速解决异步回调的问题
2016/04/05 Javascript
JavaScript数据类型转换的注意事项
2016/07/31 Javascript
vuejs在解析时出现闪烁的原因及防止闪烁的方法
2016/09/19 Javascript
JavaScript函数的4种调用方法实例分析
2019/03/05 Javascript
JS字符串与二进制的相互转化实例代码详解
2019/06/28 Javascript
使用JavaScript通过前端发送电子邮件
2020/05/22 Javascript
vue 限制input只能输入正数的操作
2020/08/05 Javascript
JS将指定的某个字符全部转换为其他字符实例代码
2020/10/13 Javascript
[42:32]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第二场 11.27
2020/12/01 DOTA
Python基于sklearn库的分类算法简单应用示例
2018/07/09 Python
解决django前后端分离csrf验证的问题
2019/02/03 Python
机器学习实战之knn算法pandas
2019/06/22 Python
Tensorflow Summary用法学习笔记
2020/01/10 Python
Python插入Elasticsearch操作方法解析
2020/01/19 Python
Luxplus瑞典:香水和美容护理折扣
2018/01/28 全球购物
企业门卫岗位职责
2013/12/12 职场文书
三年级小学生评语
2014/04/22 职场文书
体育运动口号
2014/06/09 职场文书
医院领导班子四风对照检查材料
2014/09/27 职场文书
2014院党委领导班子及其成员群众路线对照检查材料思想汇报
2014/10/04 职场文书
井冈山红色之旅心得体会
2014/10/07 职场文书
2014年英语教研组工作总结
2014/12/06 职场文书