不匹配 span 标签内的文本

3
使用Javascript,我正在尝试在页面上的某些文本周围包裹span标签,但我不想在已经在一组span标签内部的文本周围包裹标签。
目前我正在使用:
html = $('#container').html();
var regex = /([\s| ]*)(apple)([\s| ]*)/g;
html = html.replace(regex, '$1<span class="highlight">$2</span>$3');

它能工作,但如果同一个字符串被使用两次,或者该字符串出现在另一个字符串中,例如“一堆苹果”后面跟着“苹果”,那么我最终会得到这个结果:

<span class="highlight">a bunch of <span class="highlight">apples</span></span>

我不希望它在第二次出现时替换“apples”,因为它已经在 span 标签中。

这里应该匹配“apples”:

Red apples are my <span class="highlight">favourite fruit.</span>

但不是在这里:

<span class="highlight">Red apples are my favourite fruit.</span>

我尝试使用这个,但它不起作用:

([\s|&nbsp;]*)(apples).*(?!</span)

任何帮助都将不胜感激。谢谢。

http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ - Bill
1个回答

6
首先,您应该知道使用正则表达式解析html通常被认为是一个坏主意——通常建议使用Dom解析器。有了这个免责声明,我将向您展示一个简单的正则表达式解决方案。
这个问题是这个问题中解释的技术的经典案例:"regex-match a pattern, excluding..."
我们可以用一个简单美妙的正则表达式来解决它:
<span.*?<\/span>|(\bapples\b)

左侧的交替符号|匹配完整的<span.../span>标签,我们将忽略这些匹配。右侧匹配并捕获apples到第1组,我们知道它们是正确的,因为它们没有被左侧表达式匹配到。

此程序展示了如何使用正则表达式(请在在线演示的右窗格中查看结果)。请注意,在演示中,我用[span]代替了<span>,以便结果能在浏览器中显示(它会解释html):

var subject = 'Red apples are my <span class="highlight">favourite apples.</span>';
var regex = /<span.*?<\/span>|(\bapples\b)/g;
replaced = subject.replace(regex, function(m, group1) {
    if (group1 == "" ) return m;
    else return "<span class=\"highlight\">" + group1 + "</span>";
});
document.write("<br>*** Replacements ***<br>");
document.write(replaced);

参考资料


你的示例运行得非常好,而且非常简单。谢谢! - amba88
2
很高兴它能够正常工作,Arran。:) 嘿,既然你欣赏这种技术的简单和美感,我真的建议你看一下这个技术的完整讨论或者保存起来以后再看,因为它有很多有用的变体 - 我在写这个答案时非常开心。 :) - zx81
第四行应该是:if (typeof group1 == 'undefined') 或类似的语句。除此之外,回答得非常好! - Benji XVI

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接