[英]Advanced JavaScript RegExp Replacement Within HTML tags
我有運行良好的javascript代碼,例如:
var rgx = /MyName/g;
var curInnerHTML = document.body.innerHTML;
curInnerHTML = curInnerHTML.replace(rgx, "<span><span class='myName'>MyNameReplace</span></span>");
問題在於,即使在HTML屬性中包含正則表達式的情況下,它也匹配正則表達式。 如何修改正則表達式,使其只能在HTML內容中找到它? 例如,在此字符串中
<div class="someclass" title="MyName">
MyName
</div>
當前結果如下(請注意title屬性的更改):
<div class="someclass" title="<span><span class='myName'>MyNameReplace</span</span>">
<span><span class='myName'>
MyNameReplace</span></span>
</div>
但是我需要它(保持title屬性不變):
<div class="someclass" title="MyName">
<span><span class='myName'>MyNameReplace</span></span>
</div>
最好的選擇(比聽起來容易得多) 不是嘗試使用正則表達式來解析HTML,而是要利用DOM已經具有並遞歸處理文本節點這一事實。
// We use this div's `innerHTML` to parse the markup of each replacment
var div = document.createElement('div');
// This is the recursive-descent function that processes all text nodes
// within the element you give it and its descendants
function doReplacement(node, rex, text) {
var child, sibling, frag;
// What kind of node did we get?
switch (node.nodeType) {
case 1: // Element
// Probably best to leave `script` elements alone.
// You'll probably find you want to add to this list
// (`object`, `applet`, `style`, ...)
if (node.nodeName.toUpperCase() !== "SCRIPT") {
// It's an element we want to process, start with its
// *last* child and work forward, since part of what
// we're doing inserts into the DOM.
for (child = node.lastChild; child; child = sibling) {
// Before we change this node, grab a reference to the
// one that follows it
sibling = child.previousSibling;
// Recurse
doReplacement(child, rex, text);
}
}
break;
case 3: // Text
// A text node -- let's do our replacements!
// The first two deal with the fact that the text node
// may have less-than symbols or ampersands in it.
// The third, of course, does your replacement.
div.innerHTML = node.nodeValue
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(rex, text);
// Now, the `div` has real live DOM elements for the replacement.
// Insert them in front of this text node...
insertChildrenBefore(div, node);
// ...and remove the text node.
node.parentNode.removeChild(node);
break;
}
}
// This function just inserts all of the children of the given container
// in front of the given reference node.
function insertChildrenBefore(container, refNode) {
var parent, child, sibling;
parent = refNode.parentNode;
for (child = container.firstChild; child; child = sibling) {
sibling = child.nextSibling;
parent.insertBefore(child, refNode);
}
}
您會這樣稱呼:
doReplacement(document.body,
/MyName/g,
"<span><span class='myName'>MyNameReplace</span></span>");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.