【问题标题】:Stripping style attribute from paragraph tags从段落标签中剥离样式属性
【发布时间】:2014-09-22 19:43:42
【问题描述】:

我发现这个从标签中去除样式属性的正则表达式。

$content = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $_POST['content']);

它工作得很好,但我正在尝试找到一个解决方案,只将样式从段落&lt;p&gt;标签中剥离出来:

<h1 style="font: times">Hello</h1>
<p style="font: verdana">World</p>

会变成

<h1 style="font: times">Hello</h1>
<p>World</p>

我自己尝试过修改正则表达式,但我无法解决这个问题,我的正则表达式失败了。

【问题讨论】:

  • 我建议使用适当的 HTML 库。这个嵌套问题特别难以用正则表达式解决 -

    元素 不需要 需要显式关闭并没有帮助。

  • @user2864740 我明白了,我可能会看一下要使用的库。在这种情况下,虽然我可以保证它们将永远关闭。
  • 询问要使用的 which 库 - 可能。但这就是搜索引擎和研究的目的。 (一旦选择了一个库,那么关于它的使用的问题会更合适。)

标签: php html regex


【解决方案1】:

(*SKIP)(*F) 和\K

关于使用正则表达式解析 html 的所有免责声明,您可以使用这个正则表达式:

<(?!p)[^>]*>(*SKIP)(*F)|<p[^>]*\Kstyle\s*=\s*"[^"]*"

查看 the Regex Demo 底部的替换。

示例 PHP 代码

$replaced = preg_replace('~<(?!p)[^>]*>|<p[^>]*\Kstyle\s*=\s*"[^"]*"~',
                          '', 
                          $yourstring);

说明

这个问题是这个问题中向"regex-match a pattern, excluding..."解释的技术的经典案例

交替| 的左侧匹配完整的&lt;non-p tags&gt; 然后故意失败,之后引擎跳到字符串中的下一个位置。右侧匹配样式,我们知道它们是正确的,因为它们没有被左侧的表达式匹配。

参考

【讨论】:

  • FYI 添加了解释。 :)
【解决方案2】:

只需在捕获的组中添加p\b 以确保仅选择p(而不是pre):

$content = preg_replace('/(<p\b[^>]*) style=".*?"/i', '$1', $_POST['content']);

【讨论】:

  • @zx81,但是捕获组又加回来了?
  • @zx81,我的意思是替换成$1
  • 我完全错过了。抱歉,+1 :)
【解决方案3】:

避免使用正则表达式并使用正确的tool 来完成工作...

$html = <<<DATA
<h1 style="font: times">Hello</h1>
<h2 style="font: times">Hello</h2>
<p style="font: verdana">World</p>
DATA;

$dom = new DOMDocument;  
$dom->loadHTML($html); // Load your HTML

$xpath = new DOMXPath($dom);  

foreach ($xpath->query('//p[@style]') as $node) {
    $node->removeAttribute('style'); 
}

echo $dom->saveHTML(); 

输出

<h1 style="font: times">Hello</h1>
<h2 style="font: times">Hello</h2>
<p>World</p>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    相关资源
    最近更新 更多