【问题标题】:Regex to match placeholders that contain HTML within them正则表达式匹配其中包含 HTML 的占位符
【发布时间】:2016-11-18 06:31:30
【问题描述】:

我有用户可以插入到所见即所得编辑器(包含 HTML 代码)中的占位符。有时,当他们从 Word 等应用程序粘贴时,它会在其中注入 HTML。

例如:它粘贴 %<span>firstname</span>% 而不是 %firstname%

这是我的正则表达式代码示例:

$html = '

    <p>%firstname%</p>

    <p>%<span>firstname</span>%</p>

    <p>%<span class="blah">firstname</span>%</p>

    <p>%<span><span>firstname</span></span>%</p>

    <p>%<span><span><span>firstname</span></span></span>%</p>

    <p>%<span class="blah"><span>firstname</span></span>%</p>

    <div>other random <strong>HTML</strong> that needs to be preserved.</div>

';

preg_match_all(
    '/\%(?![0-9])((?:<[^<]+?>)?[a-zA-z0-9_-]+(?:[\s]?<[^<]+?>)?)\%/U', 
    $html, 
    $matches
);

echo '<pre>';
print_r($matches);
echo '</pre>';

输出如下:

Array
(
    [0] => Array
        (
            [0] => %firstname%
            [1] => %firstname%
            [2] => %firstname%
        )

    [1] => Array
        (
            [0] => firstname
            [1] => firstname
            [2] => firstname
        )

)

只要占位符中有多个跨度,它就不起作用。我不太确定要在我的正则表达式中调整什么。

/\%(?![0-9])((?:<[^<]+?>)?[a-zA-z0-9_-]+(?:[\s]?<[^<]+?>)?)\%/U

我将如何实现这一目标?

【问题讨论】:

  • @WiktorStribiżew 我的问题是我需要使用正则表达式获取字符串。
  • 使用正则表达式,您只能匹配平衡数量的标签,但您必须循环匹配并进一步处理它们或使用preg_replace_callbackthis 并使用strip_tags在匿名函数内部。问题是您无法访问从子例程调用中捕获的子字符串。这就是为什么这种类型的任务不应该真的用正则表达式来完成(一般来说,它相当麻烦)。

标签: php regex


【解决方案1】:

你真的需要一个正则表达式吗?您可以在这里简单地使用strip_tags()

试试这个:

echo strip_tags($html);

【讨论】:

  • 就像我提到的,它是所见即所得的编辑器,所以我需要在占位符之外保留 HTML 代码。我会让我的帖子更清楚。
【解决方案2】:

如果它是WYSIWYG 编辑器,您可以使用解析器和textContent 属性:

<?php

$html = '
    <p>%firstname%</p>
    <p>%<span>firstname</span>%</p>
    <p>%<span class="blah">firstname</span>%</p>
    <p>%<span><span>firstname</span></span>%</p>    
    <p>%<span><span><span>firstname</span></span></span>%</p>
    <p>%<span class="blah"><span>firstname</span></span>%</p>
    <div>A cool div with %firstname%</div>
    <span>And a very neat span with %firstname%</span>';

$dom = new DOMDocument();
$dom->loadHTML($html);

$xpath = new DOMXPath($dom);

# query only root elements here
$containers = $xpath->query("/*");
foreach ($containers as $container) {
    echo $container->textContent . "\n";
}
?>

这会输出%firstname% 几次,请参阅a demo on ideone.com

【讨论】:

  • 感谢@Jan,但我不能假设所有占位符都在

    标签中。它们可以在 div、表格单元格中,由于所见即所得允许用户编辑 HTML

【解决方案3】:

试试这个正则表达式。它应该可以帮助你!

/\%(?![0-9])(?:&lt;[^&lt;]+?&gt;)*([a-zA-z0-9_-]+)(?:[\s]?&lt;\/[^&lt;]+?&gt;)*\%/U

【讨论】:

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