0
var text='<div id="main"><div class="replace">&lt; **My Text** &gt;</div><div>Test</div></div>'

我想用 class="replace" 替换 div 并且 html 实体&lt; &gt; 在该 div 中带有一些其他文本。

即输出:

'<div id="main"> Hello **My Text** Hello <div>Test</div> </div>'

我试过了

var div = new RegExp('<[//]{0,1}(div|DIV)[^><]*>', 'g');
text = text.replace(div, "Hello");

但这将替换所有 div。

任何帮助都感激不尽!

4

4 回答 4

2

如果可以接受 Jquery 解决方案:

text = $(text) // Convert HTML string to Jquery object
         .wrap("<div />") // Wrap in a container element to make...
         .parent()        // the whole element searchable
         .find("div.replace") // Find <div class="replace" />
           .each(function()   // Iterate over each div.replace
           {
             $(this)
               .replaceWith($(this).html() // Replace div with content
                .replace("&lt;", "<sometext>")
                .replace("&gt;", "</sometext>")); // Replace text
           })
         .end().html(); // return html of $(text)

这设置text为:

<div id="main"><sometext> My Text </sometext><div>Test</div></div>

并再次将其替换回来:

text = text.replace('<sometext>', '<div class="replace">&lt;')
           .replace('</sometext>', '&gt;</div>');

http://api.jquery.com/jquery/#jQuery2
http://api.jquery.com/each/
http://api.jquery.com/find/
http://api.jquery.com/html/

于 2012-10-31T07:54:41.773 回答
2

在纯 JS 中,它会是这样的:

var elements = document.getElementsByClassName('replace');
var replaceTag = document.createElement('replacetext');
for (var i = elements.length - 1; i >= 0; i--) {
    var e = elements[i];
    e.parentNode.replaceChild(replaceTag, e);
};​
于 2012-10-31T08:03:23.973 回答
1

这是一个与您想要的匹配的疯狂正则表达式:

var text='<div id="main"><div class="replace">&lt; **My Text** &gt;</div><div>Test</div></div>'

var r = /(<(div|DIV)\s+class\s*?=('|")\s*?replace('|")\s*?>)(\s*?&lt;)(.*?)(&gt;\s*?)(<\/(div|DIV)\s*?>)/g;

可以使用以下方式进行整个更换:

text.replace(r, function () {
         return 'Hello' + arguments[6] + 'Hello';
    });

如果解决方案有问题,请告诉我:)。

顺便说一句:我完全反对像答案中的那个正则表达式......如果你用那个复杂的正则表达式做到了,那么可能有更好的方法来处理这个问题......

于 2012-10-31T09:19:43.227 回答
0

考虑改用 DOM;你已经有了你想要的结构,所以换掉节点本身(大量借用@maxwell的代码,但也移动孩子):

var elements = document.getElementsByClassName('replace');
for(var i = elements.length-1; i>= 0; --i) {
    var element = elements[i];
    var newElement = document.createElement('replacetext');
    var children = element.childNodes;
    for(var ch = 0; ch < children.length; ++i) {
        var child = children[ch];
        element.removeChild(child);
        newElement.appendChild(child);
    }
    element.parentNode.insertBefore(newElement,element);
    element.parentNode.removeChild(element);
}

然后,对于给定类的每个元素,它会将其每个子元素移动到新元素,然后使用该元素的位置插入新元素并最终移除自身。

我唯一的疑问是getElementByClassName对数组返回的item的修改是否会出问题;它可能需要在处理之前额外检查元素是否有效,或者您可能更喜欢将其编写为递归函数并首先从最深的节点处理树。

它可能看起来需要更多的工作,但这应该更快(在你改变它之后不需要重新解析 html,元素移动只是参考值分配)并且更健壮。尝试解析 HTML 可能会损害您的健康。

重读问题(总是一个好计划),你从字符串中的文本开始。如果这确实是起点(即,您不只是将其从 innerHTML 值中提取出来),那么要使用上述内容,只需创建一个临时父元素:

var fosterer = document.createElement('div');
fosterer.innerHTML = text; // your variable from the question

然后继续使用fosterer.getElementsByClassName.

于 2012-10-31T08:19:13.283 回答