在元素中的所有文本上应用RegEx

时间:2013-12-22 13:50:53

标签: javascript html regex replace

我正在尝试使用JS动态地用特定HTML元素中的链接替换特定单词。我想我会使用一个简单的RegEx:

var regEx = new RegExp('\\b'+text+'\\b', 'gi');

在上下文div的innerHTML属性中应用RegEx替换的快速'n'nasty方式:

context.innerHTML = context.innerHTML.replace(regEx, '<a href="#">'+text+"</a>");

这个问题在于它也适用于图像标题,从而打破了页面的布局。我希望它只适用于页面文本,如果可能的话,也不包括标题标签,当然还有HTML评论等。

所以我尝试了类似的东西,但它似乎根本不起作用:

function replaceText(context, regEx, replace) {
    var childNodes = context.childNodes;
    for (n in childNodes) {
        console.log(childNodes[n].nodeName);
        if (childNodes[n] instanceof Text) {
            childNodes[n].textContent = childNodes[n].textContent.replace(regEx, replace);
        } else if (childNodes[n] instanceof HTMLElement) {
            replaceText(childNodes[n], regEx, replace);
            console.log('Entering '+childNodes[n].nodeName);
        } else {
            console.log('Skipping '+childNodes[n].nodeName);
        }
    }
}

任何人都可以看到我做错了什么,或者想出更好的解决方案吗?谢谢!

更新

以下是context内容的摘要:

<h4>Newton's Laws of Motion</h4>
<p><span class="inline_title">Law No.1</span>: <span class="caption">An object at rest will remain at rest, and an object in motion will continue to move at constant velocity, unless a net force is applied.</span></p>
<ul>Consequences: <li>Conservation of Momentum in both elastic and inelastic collisions</li>
<li>Conservation of kinetic energy in elastic collisions but not inelastic.</li>
<li>Conservation of angular momentum.</li>
</ul>
<h5>Equations</h5>
<p class="equation">&rho; = mv</p>
<p>where &rho; is the momentum, and m is the mass of an object moving at constant velocity v.</p>

2 个答案:

答案 0 :(得分:2)

您可以使用:

function replaceText(context, regEx, replace)
{
    var childNodes = context.childNodes;
    for (var i = 0; i<childNodes.length; i++) {
        var childNode = childNodes[i];
        if (childNode.nodeType === 3) // 3 is for text node
            childNode.nodeValue = childNode.nodeValue.replace(regEx, replace);
        else if (childNode.nodeType === 1 && childNode.nodeName != "HEAD")
            replaceText(childNode, regEx, replace); 
    }
}
replaceText(context, /cons/ig, 'GROUIK!');

想法是在&#34; context&#34;中找到所有文本节点。 DOM树,这就是我使用递归函数搜索子节点内的文本节点的原因。

注意:我在函数中测试childNode.nodeName != "HEAD"。这只是避免特定标签的一个例子。在现实生活中,将body节点作为函数的参数更简单。

答案 1 :(得分:1)

根据我的理解,您尝试替换innerHTML中的文字,但在tags内。

首先,我尝试使用innerText代替innerHTML,但它没有给出被驱逐的结果。后来我发现@Alan Moore的answer Negative Lookahead regex 一样

(?![^<>]*>)

可用于忽略标记<>中的文本。这是我的方法

var regEx = new RegExp("(?![^<>]*>)" + title, 'gi');
context.innerHTML = context.innerHTML.replace(regEx, '<a href="#">'+text+"</a>");

以下是JSFiddle

示例