如何有选择地用HTML替换文本?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (109)

我有一个应用程序,用户可以在其中编写包含HTML代码的注释,在显示之前将其转义:

<div class="card-body">
 <p class="card-text">
  &lt;h1&gt;HOLA&lt;/h1&gt; Cita:#2&lt;h1&gt;HOLA&lt;/h1&gt; &lt;h1&gt;HOLA&lt;/h1&gt; Cita:#6&lt;h1&gt;HOLA&lt;/h1&gt; &lt;h1&gt;HOLA&lt;/h1&gt; 
 </p>
</div>

但是当用户编写像“Cita:#1”这样的特定单词时,我想用jQuery将其转换为链接,所以稍后我可以使用以下代码加载Ajax弹出窗口:

$('.card-text').each(function() {
    $(this).html($(this).text().replace(/Cita:#(\d+)/ig, '<a href="#" title="Header" data-toggle="popover" data-trigger="hover" data-content="Some content">Cita:#$1</a>'));
});

我的问题是它做得很好,但也转换了注释中的所有可能的HTML标签。

有没有办法可以忽略注释中的所有标签,只用一个链接替换“Cita:#1”这个词并使其有效?

实际:

预期:

提问于
用户回答回答于

由于您在此处控制服务器端,因此在PHP中更容易实现:

$string = '<h1>HOLA</h1> Cita:#2<h1>HOLA</h1> <h1>HOLA</h1> Cita:#6<h1>HOLA</h1> <h1>HOLA</h1>';
$string = htmlspecialchars($string);
$string = preg_replace(
    '/Cita:#(\\d+)/i',
    '<a href="#" title="Header" data-toggle="popover" data-trigger="hover" data-content="Some content">Cita:#$1</a>',
    $string
);
echo $string;

输出:

&lt;h1&gt;HOLA&lt;/h1&gt; <a href="#" title="Header" data-toggle="popover" data-trigger="hover" data-content="Some content">Cita:#2</a>&lt;h1&gt;HOLA&lt;/h1&gt; &lt;h1&gt;HOLA&lt;/h1&gt; <a href="#" title="Header" data-toggle="popover" data-trigger="hover" data-content="Some content">Cita:#6</a>&lt;h1&gt;HOLA&lt;/h1&gt; &lt;h1&gt;HOLA&lt;/h1&gt;
用户回答回答于

您需要做的是分离文本的匹配部分并将它们作为HTML字符串处理,但是转义*文本的其余部分。由于正则表达式匹配提供匹配的索引,因此这很容易做到。

$('.card-text').each(function() {
    var before = "";
    var after = $(this).text();
    var link = "";
    // look for each match in the string
    while (match = after.match(/\b(Cita:#(\d+))\b/i)) {
        // isolate the portion before the match and escape it, this will become the output
        before += $("<div>").text(after.substring(0, match.index)).html();
        // isolate the portion after the match, for use in the next loop
        after = after.substring(match.index + match[1].length);
        // build a link and append it to our eventual output
        before += match[1].replace(/Cita:#(\d+)/i, '<a href="#" title="Header" data-toggle="popover" data-trigger="hover" data-content="Some content">Cita:#$1</a>');
    }
    // deal with the final bit of the string, which needs to be escaped
    this.innerHTML = before + $("<div>").text(after).html();
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-body">
 <p class="card-text">
 &lt;span class="foo"&gt;Here is some text. &lt;b&gt;Cita:#1&lt;/b&gt; and &lt;b&gt;Cita:#2&lt;/b&gt;&lt;/span&gt;
 </p>
</div>

*我们使用jQuery构建元素,将字符串作为该元素的文本内容传递,最后获取HTML输出:

htmlString = "<div>foo</div>";
console.log(
    $("<div>").text(htmlString).html()
);

输出:

&lt;div&gt;foo&lt;/div&gt;

扫码关注云+社区

领取腾讯云代金券