关于preg_match正则匹配的一些问题总结
preg_match,preg_match_all,preg_replace,preg_grep是php中正则匹配的一些函数,但在使用正则表达式应用时会遇到一些问题,总结如下:
1.Warning: preg_match() [function.preg-match]: Unknown modifier的解决方法
用preg_match()函数做程序的时候,有时我们会遇到这样的提示:
Warning: preg_match() [function.preg-match]: Unknown modifier;
比方说:
Warning: preg_match() [function.preg-match]: Unknown modifier 'f' inX:kfqixj.php on line 85。
分析一下这个问题:
modifier在这里可以理解为“修饰符”,那么就是“不能识别修饰符”。
其实大多数情况是缺少了转义字符,解决的方法是:把分界符或转义字符之类的填写完整。
理解“转义字符”
所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。
2.preg_match匹配字符怎样用变量代替?
假设本来代码是:Preg_match('/<a href="(.+?)">(.+?)SAT030-54A(.+?)<\/a>/',$fp,$out);
如果我想把SAT030-54A用变量代替:
$a="SAT030-54A";
preg_match('/<a href="(.+?)">(.+?)$a(.+?)<\/a>/',$fp,$out);
或Preg_match('/<a href="(.+?)">(.+?).$a.(.+?)<\/a>/',$fp,$out);
以上两个都不对,请问应该怎样?
第一种:
把这些,'/<a href="(.+?)">(.+?)SAT030-54A(.+?)<\/a>/',换成$a
第二种
把单引号换成双引号:
preg_match('/<a href="(.+?)">(.+?)$a(.+?)<\/a>/',$fp,$out);
换成
preg_match("/<a href="(.+?)">(.+?)$a(.+?)<\/a>/",$fp,$out);
3.PHP正则匹配的问题
我想检测字符中是否有中文,用正则[^\x00-\xff],在regex tester 中成功,怎么在php中不行呢?
$regv="/[^\x00-\xff]/";
$match="wom是";
$result=preg_match($regv,$match,$arr);
if($result){
echo "ok<br>";
print_r($arr);}
else
echo "fail";
还提示警告
Warning: preg_match() [function.preg-match]: No ending delimiter '/' found in D:\test.php on line 41
貌似,改成单引号就没这个问题了,$regv=’/[^\x00-\xff]/‘; ,不过你这句句子可能有问题,我判断出来是false的,我也不太懂中文的正则。。。 至于为什么单引号,因为在双引号里默认不识\,实在想用双引号写成\\
4.解决preg_match匹配过多字符长度的限制的思路分析
今天在写采集程序的时候,使用到了preg_match,但是有几个页面始终采集不下来。反复看了N遍的正则,没有发现有问题。于是开始怀疑preg_match是否对匹配的字符串有长度限制
但是官方的文档里面没有说明这一点。
于是开始测试:将要匹配的字串不断缩短,直到缩为原来1/5的时候可以正常匹配了,所以更加确定了。
到google里一搜,终于找到了解决方案:在php.ini中加入(随便放到哪里,我是直接放第一行的)
pcre.backtrack_limit=-1
再次使用preg_match函数测试一下,大概1300多行上万个字符的字符串也能够匹配了。
项目中,用preg_match正则提取目标内容,死活有问题,代码测得死去活来。
后来发现“pcre.backtrack_limit ”的值默认只设了100000。
解决办法:ini_set(‘pcre.backtrack_limit', 999999999);
注:这个参数在php 5.2.0版本之后可用。
另外说说关于:pcre.recursion_limit
pcre.recursion_limit是PCRE的递归限制,这个项如果设很大的值,会消耗所有进程的可用堆栈,最后导致PHP崩溃。
也可以通过修改配置来限制:ini_set(‘pcre.recursion_limit', 99999);
实际项目应用中,最好也对内存进行限定设置:ini_set(‘memory_limit', '64M'); , 这样就比较稳妥妥嘎。
5.preg_match长字符串匹配失败问题解决
今天在查一个问题,用正则从字符串中提取内容失败,反复检查字符串和正则表达式,都没有问题。又写了小脚本测试,还没有问题,回到代码中调试,又失败了。
字符串比较长,因此怀疑是不是preg_match也有字符串长度限制,果然!
preg_match、preg_match_all都会有这种情况。
解决方法:
1、ini_set(‘pcre.backtrack_limit’, 1000000); //默认的只有100000
2、修改php.ini 的pcre.backtrack_limit参数,使之支持更大的字符串。加入配置:pcre.backtrack_limit=-1
评论

React 18的并发渲染确实是个重大改进,我们在项目中已经升级使用,性能提升明显!