先说一下,我是怎么遇到这个问题的,写html的时候没要求换行<br>,线条<hr>加/。后来呢客户要示把<br>,<hr>换成<br />,<hr />,因为网站有统一的入口,所以我把html输出的地方加了,正则进行替换,这是最方便的一种方式,所以在做这个工作之前我在本地做了一下测试,preg_replace我经常用,算是很熟了,但是用的过程中还是遇到一些问题,挺郁闷,我把问题提出来:
一,这种情况是我想要的情况
<?php $string = "asdf <br> 444444 <br ><br /> 3333333 <hr> bbbbb <hr > 12312."; $patterns[0] = "/<hr[^<>\/]*>/i"; //匹配$string里面没有/的hr $patterns[1] = "/<br[^<>\/]*>/i"; //匹配$string里面没有/的br $replacements[0] = "<hr />"; //将string里面的没有/的hr,换成有/的hr $replacements[1] = "<br />"; //将string里面的没有/的br,换成有/的br $aaa = preg_replace($patterns, $replacements, $string); //进行替换 echo $aaa; //结果是:asdf <br /> 444444 <br /><br /> 3333333 <hr /> bbbbb <hr /> 12312. ?>
二,问题情况
<?php $string = "asdf <br> 444444 <br ><br /> 3333333 <hr> bbbbb <hr > 12312."; $patterns[0] = "/<hr[^<>\/]*>/i"; //匹配$string里面没有/的hr $patterns[1] = "/<br[^<>\/]*>/i"; //匹配$string里面没有/的br $replacements[1] = "<br />"; //将string里面的没有/的br,换成有/的br $replacements[0] = "<hr />"; //将string里面的没有/的hr,换成有/的hr $aaa = preg_replace($patterns, $replacements, $string); //进行替换 echo $aaa; //结果是:asdf <hr /> 444444 <hr /><br /> 3333333 <br /> bbbbb <br /> 12312. ?>
不知道你有没有发现上面二个例子的不同呢?不同之处就在$replacements[0]在前一行,还是在后一行的问题,就这么一点点的区别,带来的结果却是完全相反的。请使用者小心使用。
$replacements[0] = "<hr />";
$replacements[1] = "<br />";
$replacements[1] = "<br />";
$replacements[0] = "<hr />";
不明白的地方就是上面二个例子中,都以数字为下标,谁在前在后不都是一样的吗?二个例子当中,我把数组都打印出来了,完全一样,难道php读取数组数据,还会去看看谁在前赋值,谁在后赋值?
如果 pattern 和 replacement 都是数组,将以其键名在数组中出现的顺序来进行处理。这不一定和索引的数字顺序相同。如果使用索引来标识哪个 pattern 将被哪个 replacement 来替换,应该在调用 preg_replace() 之前用 ksort() 对数组进行排序。
上面的一段话是在官方网站上找到的,已经很明显的说明了,不一定和索引的数字顺序相同。如果不以数字顺序来定位的话,我很想知道他是怎么区分,$replacements[0] = "<hr />"; 在前在后的,难道真是以赋值的前后来区分。
如果真是以赋值的前后顺序来区分,那为什么还要用数组,并且还可以带有下标,这不是引人误入歧途吗?
有没有更有说服力的解释呢?
在向请教后,给了一个不错的解答$aaa = preg_replace("/<(br|hr)[^<>]*>/iU", "<$1 />", $string);
转载请注明
作者:海底苍鹰
地址:http://blog.51yip.com/php/892.html
$patterns[0] = "/]*?>/i"; //匹配$string里面没有/的hr
$patterns[1] = "/]*?>/i"; //匹配$string里面没有/的br
呵呵,正则真强大,preg_replace真强大,我是来学习的。博主的正则规则忘记加非贪婪了, 这一点要值得注意