preg_replace贪婪与非贪婪模式效果一致?移除特定div遇问题
问题分析与解决
你的代码里存在两个关键问题,导致不管用贪婪还是非贪婪模式,都无法成功移除目标div标签:
1. 正则匹配的实体与字符串中的实体不匹配
看你的输入字符串,目标div里的内容是 (也就是HTML转义后的 ),但你的正则表达式里写的是 ——这两个是完全不同的字符串,正则自然找不到匹配项,这是核心问题!
2. 用(.*)匹配div属性存在风险
即使修正了实体问题,(.*)会匹配任意字符(包括换行,因为用了s修饰符):贪婪模式下可能从第一个<div开始,一直匹配到最后一个</div>的结尾;非贪婪模式也可能因为意外字符导致匹配范围出错。更稳妥的方式是用[^>]*匹配div的属性部分,它只会匹配到下一个>为止,不会跨标签。
修正后的代码
下面是调整后的解决方案,既能精准匹配仅包含&nbsp;的div,又能避免跨标签匹配的问题:
$s = '<div style="text-align: justify;">Some text</div>'; $s .= '<div style="text-align: justify;">&nbsp;</div>'; $s .= '<div style="text-align: justify;">Some more text</div>'; // 精准匹配仅含&nbsp;的div,允许属性存在,同时避免跨标签 $fixed = preg_replace('/<div[^>]*>&nbsp;<\/div>/is', '', $s); print $fixed;
如果需要兼容div内部有空白字符(比如换行、空格)的情况,可以调整正则为:
$fixed = preg_replace('/<div[^>]*>\s*&nbsp;\s*<\/div>/is', '', $s);
这段代码会输出:
<div style="text-align: justify;">Some text</div><div style="text-align: justify;">Some more text</div>
目标div已经被成功移除了。
额外说明
[^>]*:匹配除了>之外的任意字符,确保只在当前div标签的属性部分匹配,不会跨到其他标签。\s*:匹配任意数量的空白字符(包括空格、换行、制表符等),兼容div内部可能存在的空白。is修饰符:i忽略大小写(div标签大小写不影响,保留也没问题),s让.匹配换行符(不过我们用了[^>]*,这个修饰符在这里作用不大,但保留也不影响)。
内容的提问来源于stack exchange,提问作者Werner
相关产品推荐
相关产品推荐

