PHP Perl兼容正则表达式 和 POSIX扩展表达式

2009年5月2日星期六

PHP Perl兼容正则表达式 和 POSIX扩展表达式

^-?[0-9]*.?[0-9]*$所有小树
通用字符簇:
[[:alpha:]]任何字母
[[:digit:]]任何数字
============
常用的正则表达式
1、非负整数:^\d+$
2、正整数:^[0-9]*[1-9][0-9]*$
3、非正整数:^((-\d+)|(0+))$
4、负整数:^-[0-9]*[1-9][0-9]*$
5、整数:^-?\d+$
6、非负浮点数:^\d+(\.\d+)?$
7、正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
8、非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$
9、负浮点数:^(-((正浮点数正则式)))$
10、英文字符串:^[A-Za-z]+$
11、英文大写串:^[A-Z]+$
12、英文小写串:^[a-z]+$
13、英文字符数字串:^[A-Za-z0-9]+$
14、英数字加下划线串:^\w+$
15、E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
16、URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$
=============
Perl和POSIX表达式的写法区别
pregereg
\d+[0-9]*
[abc\d+]abc[0-9]*//perl中字符都要加上分隔符[]或()或||
\w[A-Za-z0-9_]
[log]$iereg中模式修正符i,m,s等无效,所以最接近的表达式是:log$
perl中字符串必须包含在[],()之间或是紧邻^、$
============
preg_grep

(PHP4,PHP5)

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

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

flags可以是以下标记:

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

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

Example#1preg_grep()例子
?php
//returnallarrayelements
//containingfloatingpointnumbers
$fl_array=preg_grep(/^(\d+)?\.\d+$/,$array);
?

==================================
ereg_replace
(PHP4,PHP5)

ereg_replace正则表达式替换

说明
stringereg_replace(string$pattern,string$replacement,string$string)
本函数在string中扫描与pattern匹配的部分,并将其替换为replacement。

返回替换后的字符串。(如果没有可供替换的匹配项则会返回原字符串。)

如果pattern包含有括号内的子串,则replacement可以包含形如\\digit的子串,这些子串将被替换为数字表示的的第几个括号内的子串;\\0则包含了字符串的整个内容。最多可以用九个子串。括号可以嵌套,此情形下以左圆括号来计算顺序。

如果未在string中找到匹配项,则string将原样返回。

例如,下面的代码片断输出Thiswasatest三次:


Example#1ereg_replace()例子

?php
$string=Thisisatest;
echostr_replace(is,was,$string);
echoereg_replace(()is,\\1was,$string);
echoereg_replace((()is),\\2was,$string);
?

要注意的一点是如果在replacement参数中使用了整数值,则可能得不到所期望的结果。这是因为ereg_replace()将把数字作为字符的序列值来解释并应用之。例如:


Example#2ereg_replace()例子

?php
/*不能产生出期望的结果*/
$num=4;
$string=Thisstringhasfourwords.;
$string=ereg_replace('four',$num,$string);
echo$string;/*Output:'Thisstringhaswords.'*/

/*本例工作正常*/
$num='4';
$string=Thisstringhasfourwords.;
$string=ereg_replace('four',$num,$string);
echo$string;/*Output:'Thisstringhas4words.'*/
?


Example#3将URL替换为超连接

?php
$text=ereg_replace([[:alpha:]]+://[^[:space:]]+[[:alnum:]/],
ahref=\\\0\\\0/a,$text);
?

Tip
preg_replace()函数使用了Perl兼容正则表达式语法,通常是比ereg_replace()更快的替代方案。


===========================================

模式修正符
(Noversioninformationavailable,mightbeonlyinCVS)

模式修正符解说正则表达式模式中使用的修正符

说明
下面列出了当前在PCRE中可能使用的修正符。括号中是这些修正符的内部PCRE名。修正符中的空格和换行被忽略,其它字符会导致错误。


i(PCRE_CASELESS)
如果设定此修正符,模式中的字符将同时匹配大小写字母。
m(PCRE_MULTILINE)
默认情况下,PCRE将目标字符串作为单一的一行字符所组成的(甚至其中包含有换行符也是如此)。行起始元字符(^)仅仅匹配字符串的起始,行结束元字符($)仅仅匹配字符串的结束,或者最后一个字符是换行符时其前面(除非设定了D修正符)。这和Perl是一样的。当设定了此修正符,行起始和行结束除了匹配整个字符串开头和结束外,还分别匹配其中的换行符的之后和之前。这和Perl的/m修正符是等效的。如果目标字符串中没有\n字符或者模式中没有^或$,则设定此修正符没有任何效果。
s(PCRE_DOTALL)
如果设定了此修正符,模式中的圆点元字符(.)匹配所有的字符,包括换行符。没有此设定的话,则不包括换行符。这和Perl的/s修正符是等效的。排除字符类例如[^a]总是匹配换行符的,无论是否设定了此修正符。
x(PCRE_EXTENDED)
如果设定了此修正符,模式中的空白字符除了被转义的或在字符类中的以外完全被忽略,在未转义的字符类之外的#以及下一个换行符之间的所有字符,包括两头,也都被忽略。这和Perl的/x修正符是等效的,使得可以在复杂的模式中加入注释。然而注意,这仅适用于数据字符。空白字符可能永远不会出现于模式中的特殊字符序列,例如引入条件子模式的序列(?(中间。
e
如果设定了此修正符,preg_replace()在替换字符串中对逆向引用作正常的替换,将其作为PHP代码求值,并用其结果来替换所搜索的字符串。
只有preg_replace()使用此修正符,其它PCRE函数将忽略之。

Note:本修正符在PHP3中不可用。


A(PCRE_ANCHORED)
如果设定了此修正符,模式被强制为anchored,即强制仅从目标字符串的开头开始匹配。此效果也可以通过适当的模式本身来实现(在Perl中实现的唯一方法)。
D(PCRE_DOLLAR_ENDONLY)
如果设定了此修正符,模式中的美元元字符仅匹配目标字符串的结尾。没有此选项时,如果最后一个字符是换行符的话,美元符号也会匹配此字符之前(但不会匹配任何其它换行符之前)。如果设定了m修正符则忽略此选项。Perl中没有与其等价的修正符。
S
当一个模式将被使用若干次时,为加速匹配起见值得先对其进行分析。如果设定了此修正符则会进行额外的分析。目前,分析一个模式仅对没有单一固定起始字符的non-anchored模式有用。
U(PCRE_UNGREEDY)
本修正符反转了匹配数量的值使其不是默认的重复,而变成在后面跟上?才变得重复。这和Perl不兼容。也可以通过在模式之中设定(?U)修正符或者在数量符之后跟一个问号(如.*?)来启用此选项。
X(PCRE_EXTRA)
此修正符启用了一个PCRE中与Perl不兼容的额外功能。模式中的任何反斜线后面跟上一个没有特殊意义的字母导致一个错误,从而保留此组合以备将来扩充。默认情况下,和Perl一样,一个反斜线后面跟一个没有特殊意义的字母被当成该字母本身。当前没有其它特性受此修正符控制。
u(PCRE_UTF8)
此修正符启用了一个PCRE中与Perl不兼容的额外功能。模式字符串被当成UTF-8。本修正符在Unix下自PHP4.1.0起可用,在win32下自PHP4.2.3起可用。自PHP4.3.5起开始检查模式的UTF-8合法性。

g(全文查找出现的所有pattern)
gi(全文查找、忽略大小写)
========================
preg_split
(PHP4,PHP5)

preg_split用正则表达式分割字符串

说明
arraypreg_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
如果设定了本标记,定界符模式中的括号表达式也会被捕获并返回。本标记添加于PHP4.0.5。
PREG_SPLIT_OFFSET_CAPTURE
如果设定了本标记,如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其在subject中的偏移量。本标记自PHP4.3.0起可用。


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


Example#1preg_split()例子:取得搜索字符串的成分

?php
//splitthephrasebyanynumberofcommasorspacecharacters,
//whichinclude,\r,\t,\nand\f
$keywords=preg_split(/[\s,]+/,hypertextlanguage,programming);
?


Example#2将字符串分割成字符

?php
$str='string';
$chars=preg_split('//',$str,-1,PREG_SPLIT_NO_EMPTY);
print_r($chars);
?


Example#3将字符串分割为匹配项及其偏移量

?php
$str='hypertextlanguageprogramming';
$chars=preg_split('//',$str,-1,PREG_SPLIT_OFFSET_CAPTURE);
print_r($chars);
?
本例将输出:

Array
(
[0]=Array
(
[0]=hypertext
[1]=0
)

[1]=Array
(
[0]=language
[1]=10
)

[2]=Array
(
[0]=programming
[1]=19
)

)


Note:flags是PHP4Beta3添加的。



===========================
preg_replace_callback
(PHP4=4.0.5,PHP5)

preg_replace_callback用回调函数执行正则表达式的搜索和替换

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

Example#1preg_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
?

Example#2preg_replace_callback()和create_function()

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

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


==========================
flags可以是以下标记:

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

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


Example#1preg_grep()例子

?php
//returnallarrayelements
//containingfloatingpointnumbers
$fl_array=preg_grep(/^(\d+)?\.\d+$/,$array);
?
================================
preg_match
(PHP4,PHP5)

preg_match进行正则表达式匹配

说明
intpreg_match(string$pattern,string$subject[,array$matches[,int$flags]])
在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。

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


Example#1在文本中搜索php

?php
//模式定界符后面的i表示不区分大小写字母的搜索
if(preg_match(/php/i,PHPisthewebscriptinglanguageofchoice.)){
printAmatchwasfound.;
}else{
printAmatchwasnotfound.;
}
?


Example#2搜索单词web

?php
/*模式中的\b表示单词的边界,因此只有独立的web单词会被匹配,
*而不会匹配例如webbing或cobweb中的一部分*/
if(preg_match(/\bweb\b/i,PHPisthewebscriptinglanguageofchoice.)){
printAmatchwasfound.;
}else{
printAmatchwasnotfound.;
}

if(preg_match(/\bweb\b/i,PHPisthewebsitescriptinglanguageofchoice.)){
printAmatchwasfound.;
}else{
printAmatchwasnotfound.;
}
?


Example#3从URL中取出域名

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

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

domainnameis:php.net


========================
preg_match_all
(PHP4,PHP5)

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

说明
intpreg_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,
bexample:/bdivalign=leftthisisatest/div,
$out,PREG_PATTERN_ORDER);
print$out[0][0].,.$out[0][1].\n;
print$out[1][0].,.$out[1][1].\n;
?
本例将输出:

bexample:/b,divalign=leftthisisatest/div
example:,thisisatest

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


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

?php
preg_match_all(|[^]+(.*)/[^]+|U,
bexample:/bdivalign=leftthisisatest/div,
$out,PREG_SET_ORDER);
print$out[0][0].,.$out[0][1].\n;
print$out[1][0].,.$out[1][1].\n;
?
本例将输出:

bexample:/b,example:
divalign=leftthisisatest/div,thisisatest


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

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


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

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


Example#1从某文本中取得所有的电话号码

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


Example#2搜索匹配的HTML标记(greedy)

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

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

for($i=0;$icount($matches[0]);$i++){
echomatched:.$matches[0][$i].\n;
echopart1:.$matches[1][$i].\n;
echopart2:.$matches[3][$i].\n;
echopart3:.$matches[4][$i].\n\n;
}
?
本例将输出:

matched:bboldtext/b
part1:b
part2:boldtext
part3:/b

matched:ahref=howdy.htmlclickme/a
part1:ahref=howdy.html
part2:clickme
part3:/a

==============================
preg_replace
字符串比对解析并取代。

语法:mixedpreg_replace(mixedpattern,mixedreplacement,mixedsubject);

返回值:混合类型资料

函数种类:资料处理
内容说明
本函数以pattern的规则来解析比对字符串subject,欲取而代之的字符串为参数replacement。返回值为混合类型资料,为取代后的字符串结果。

使用范例
下例返回值为$startDate=6/19/1969

?php
$patterns=array(/(19|20\d{2})-(\d{1,2})-(\d{1,2})/,/^\s*{(\w+)}\s*=/);
$replace=array(\\3/\\4/\\1,$\\1=);
printpreg_replace($patterns,$replace,{startDate}=1969-6-19);
?


=============================
PHP正则表达式使用详解

正则表达式是由普通字符(例如字符a到z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
可以通过在一对分隔符之间放入表达式模式的各种组件来构造一个正则表达式,即/expression/

普通字符

由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符,所有数字,所有标点符号以及一些符号。
非打印字符

字符含义

\cx匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的'c'字符。
\f匹配一个换页符。等价于\x0c和\cL。
\n匹配一个换行符。等价于\x0a和\cJ。
\r匹配一个回车符。等价于\x0d和\cM。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。
\S匹配任何非空白字符。等价于[^\f\n\r\t\v]。
\t匹配一个制表符。等价于\x09和\cI。
\v匹配一个垂直制表符。等价于\x0b和\cK。

0 评论:

发表评论