函数符
描述
*?
零次或多次,但尽可能少的匹配
+?
一次或多次,但尽可能少的匹配
??
0次或1次,但尽可能少的匹配
{n,}?
至少n次,但尽可能少的匹配
{n,m}?
n到m次 ,但尽可能少的匹配
php正则表达式之回溯与固态分组
回溯
首先我们需要清楚什么是回溯,回溯就像是在走岔路口,当遇到岔路的时候就先在每个路口做一个标记。如果走了死路,就可以照原路返回,直到遇见之前所做过的标记,标记着还未尝试过的道路。如果那条路也走不能,可以继续返回,找到下一个标记,如此重复,直到找到出路,或者直到完成所有没有尝试过的路。首先我们看例题
$str='aageacwgewcaw'; $pattern='/a\w*c/i'; $str=preg_match($pattern, $str);
看到上面的程序,可能都清楚是什么意思,就是匹配$str是否包含这样一个由”a+0个或多个字母+c”不区分大小写的字符串。但是至于程序怎样去匹配的呢?匹配的过程中,回溯了多少次呢?
匹配过程
接下来操作描述
‘a\w*c'中a匹配到'aageacwgewcaw'中第一个字符a
\w进行下一个字符匹配
因为\w是贪婪匹配,会一直匹配到'aageacwgewcaw'中最后一个字符w
c进行下一个字符匹配时
‘a\w*c'中c发现没有可以匹配的
于是\w匹配进行第一次回溯,匹配到倒数第二个字符a
‘a\w*c'中c发现还是没有可以匹配的
于是\w匹配进行第二次回溯,匹配到倒数第三个字符c
‘a\w*c'中c匹配成功
匹配结束返回结果
现在,如果我们将pattern改为pattern='/a\w*?c/i';又会回溯多少次呢?正确答案是回溯四次。
固态分组
固态分组,目的就是减少回溯次数, 使用(?>…)括号中的匹配时如果产生了备选状态,那么一旦离开括号便会被立即 引擎抛弃掉。举个典型的例子如: ‘\w+:'这个表达式在进行匹配时的流程是这样的,会优先去匹配所有的符合\w的字符,假如字符串的末尾没有':',即匹配没有找到冒号,此时触发回溯机制,他会迫使前面的\w+释放字符,并且在交还的字符中重新尝试与':'作比对。但是问题出现在这里: \w是不包含冒号的,显然无论如何都不会匹配成功,可是依照回溯机制,引擎还是得硬着头皮往前找,这就是对资源的浪费。所以我们就需要避免这种回溯,对此的方法就是将前面匹配到的内容固化,不令其存储备用状态!,那么引擎就会因为没有备用状态可用而只得结束匹配过程。大大减少回溯的次数。
如下代码,就不会进行回溯:
$str='nihaoaheloo'; $pattern='/(?>\w+):/'; $rs=preg_match($pattern, $str);
当然有的时候,又需慎用固态分组,如下,我要检查$str中是否包含以a结尾的字符串,很明显是包含的,但是因为使用了固态分组,反而达不到我们想要的效果
$str='nihaoahelaa'; $pattern1='/(?>\w+)a/'; $pattern2='/\w+a/'; $rs=preg_match($pattern1, $str);//0 $rs=preg_match($pattern2, $str);//1
php中其他常用字符串操作函数
字符串截取截取
string substr ( string string,intstart [, int length])stringmbsubstr(stringstr , int start[,intlength = NULL [, string $encoding = mb_internal_encoding() ]] )
字符串中大小写转换
strtoupper
strtolower
ucfirst
ucwords
字符串比较
-strcmp、strcasecmp、strnatcmp
字符串过滤
字符串翻转
strrev($str);
字符串随机排序
string str_shuffle ( string $str )
补充
怎样进行邮箱匹配,url匹配,手机匹配
使用preg_match函数进行匹配,以下内容从TP中复制而来。
邮箱验证
pattern=′/\w+([−+.]\w+)∗@\w+([−.]\w+)∗\.\w+([−.]\w+)∗/';
url匹配
pattern='/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?/';
手机验证
pattern=′/1[3458]\d10/';
php中正则的优缺点