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

2018-09-07 17:09

阅读:273

  
preg_grep
(PHP4,PHP5)

preg_grep--返回与模式匹配的数组单元
说明
arraypreg_grep(stringpattern,arrayinput[,intflags])


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

flags可以是以下标记:


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


自PHP4.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
(PHP3>=3.0.9,PHP4,PHP5)

preg_match--进行正则表达式匹配
说明
intpreg_match(stringpattern,stringsubject[,arraymatches[,intflags]])


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

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

flags可以是下列标记:


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

flags参数自PHP4.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,PHPistheweb45scriptingweb34languageofchoice.,$match)){
printAmatchwasfound.;
print_r($match);
}else{
printAmatchwasnotfound.;
}

?>

<?php
//从URL中取得主机名
preg_match(/^(http:\/\/)?([^\/]+)/i,

$host=$matches[2];

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

preg_match_all
(PHP3>=3.0.9,PHP4,PHP5)

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

手册上该函数的解释非常明确,就不多做说明了。
说明
intpreg_match_all(stringpattern,stringsubject,arraymatches[,intflags])


在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><divalign=left>thisisatest</div>,
$out,PREG_PATTERN_ORDER);
print$out[0][0].,.$out[0][1].\n;
print$out[1][0].,.$out[1][1].\n;
?>

本例将输出:

<b>example:</b>,<divalign=left>thisisatest</div>
example:,thisisatest


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



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


<?php
preg_match_all(<[^>]+>(.*)</[^>]+>U,
<b>example:</b><divalign=left>thisisatest</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:
<divalign=left>thisisatest</div>,thisisatest




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

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


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

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

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

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



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

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

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

for($i=0;$i<count($matches[0]);$i++){
echomatched:.$matches[0][$i].\n;
echopart1:.$matches[1][$i].\n;
echopart2:.$matches[3][$i].\n;
echopart3:.$matches[4][$i].\n\n;
}
?>



preg_quote
(PHP3>=3.0.9,PHP4,PHP5)

preg_quote--转义正则表达式字符
说明
stringpreg_quote(stringstr[,stringdelimiter])


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

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

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

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

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

例:例子1.preg_quote()例子

<?php
$keywords=$40forag3/400;
$keywords=preg_quote($keywords,/);
echo$keywords;//returns\$40forag3\/400
?>



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

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

$textbody=Thisbookis*very*difficulttofind.;
$word=*very*;
$textbody=preg_replace(/.preg_quote($word)./,
<i>.$word.</i>,
$textbody);
?>



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

preg_replace
(PHP3>=3.0.9,PHP4,PHP5)

preg_replace--执行正则表达式的搜索和替换
说明
mixedpreg_replace(mixedpattern,mixedreplacement,mixedsubject[,intlimit])


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

replacement可以包含\\n形式或(自PHP4.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参数是PHP4.0.1pl2之后加入的。

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

preg_replace_callback
(PHP4>=4.0.5,PHP5)

preg_replace_callback--用回调函数执行正则表达式的搜索和替换
说明
mixedpreg_replace_callback(mixedpattern,callbackcallback,mixedsubject[,intlimit])


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

例子1.preg_replace_callback()例子

<?php
//此文本是用于2002年的,
//现在想使其能用于2003年
$text=Aprilfoolsdayis04/01/2002\n;
$text.=Lastchristmaswas12/24/2001\n;

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

echopreg_replace_callback(
(\d{2}/\d{2}/)(\d{4}),
next_year,
$text);

//结果为:
//Aprilfoolsdayis04/01/2003
//Lastchristmaswas12/24/2002
?>


Youlloftenneedthecallbackfunctionforapreg_replace_callback()injustoneplace.Inthiscaseyoucanusecreate_function()todeclareananonymousfunctionascallbackwithinthecalltopreg_replace_callback().Bydoingitthiswayyouhaveallinformationforthecallinoneplaceanddonotclutterthefunctionnamespacewithacallbackfunctionsnamenotusedanywhereelse.

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

例子2.preg_replace_callback()和create_function()

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

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


最后是

preg_split
(PHP3>=3.0.9,PHP4,PHP5)

preg_split--用正则表达式分割字符串
不再赘述。
说明
arraypreg_split(stringpattern,stringsubject[,intlimit[,intflags]])


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

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

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


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

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

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


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


评论


亲,登录后才可以留言!