匹配不在span标签内的文本

amb*_*a88 3 html javascript regex

使用Javascript,我试图在页面上的某些文本周围包装span标签,但我不想在一组span标签内部的文本周围包装标签.

目前我正在使用:

html = $('#container').html();
var regex = /([\s| ]*)(apple)([\s| ]*)/g;
html = html.replace(regex, '$1<span class="highlight">$2</span>$3');
Run Code Online (Sandbox Code Playgroud)

它可以工作,但如果它在同一个字符串上使用两次,或者如果字符串稍后出现在另一个字符串中,例如'一堆苹果',然后是'苹果',我最终得到这个:

<span class="highlight">a bunch of <span class="highlight">apples</span></span>
Run Code Online (Sandbox Code Playgroud)

我不希望它第二次替换'apples',因为它已经在span标签内.

它应该符合'苹果'这里:

Red apples are my <span class="highlight">favourite fruit.</span>
Run Code Online (Sandbox Code Playgroud)

但不是这里:

<span class="highlight">Red apples are my favourite fruit.</span>
Run Code Online (Sandbox Code Playgroud)

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

([\s|&nbsp;]*)(apples).*(?!</span)
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.谢谢.

zx8*_*x81 6

首先,您应该知道使用正则表达式解析html通常被认为是一个坏主意 - 通常建议使用Dom解析器.有了这个免责声明,我将向您展示一个简单的正则表达式解决方案.

这个问题是这个问题中解释为"正则表达式匹配模式,排除......"的经典案例.

我们可以用一个非常简单的正则表达式解决它:

<span.*?<\/span>|(\bapples\b)
Run Code Online (Sandbox Code Playgroud)

交替的左侧 |匹配完整<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);
Run Code Online (Sandbox Code Playgroud)

参考

  • 很高兴它有效,阿兰.:)嘿,既然你欣赏这种技术的简洁和美丽,我真的建议你看一下[技术的全面讨论](http://stackoverflow.com/q/23589174/)或保存它以供日后使用,因为它有许多有用的变化 - 我有很多乐趣写这个答案.:) (2认同)