我正在尝试替换某个单词的所有实例,在某些HTML标记之间说“foo”。
<span id=foo> blah blah foo blah foo blah </span>
我想用bar替换不在标签中的所有foo实例,因此最终结果是:
<span id=foo> blah blah bar blah bar blah </span>
请注意,span标记中的“foo”尚未替换。
我可以设法用我的正则表达式替换“foo”的第一个(或最后一个),但不是多个实例。这种情况我应该放弃而不是试图用正则表达式解析它吗?
这是有效的正则表达式:
RegExp('(>[\\w\\s]*)\\bfoo\\b([\\w\\s]*<)',"ig"
或没有javascript语法:
s/>([\w\s]*)\bfoo\b([\w\s]*<)/
此语法允许我匹配(或应)匹配
之类的内容[foo]但不是bar-foo或barfoobar ......任何被替换的foo都需要站在它自己的身上,它不能包含在另一个词中。
作为一个注释,“blah blah”具有不同的长度,可以是许多不同的单词,没有单词或这些的任何组合。
感谢您的任何建议。
答案 0 :(得分:3)
我不知道以前是否有人提到这一点,但是:
请勿使用REGEX来操作HTML。
这是一个糟糕的工具,无法处理HTML的复杂性。如果你开始替换标记内的字符串,你可以很容易地给自己不仅仅是破坏的标记,而且还有HTML注入漏洞可能导致跨站点脚本漏洞。这样:
(>[\\w\\s]*)
不够,以确保您正在更改的HTML不在标记中。在属性值中包含>
字符是完全有效的,更不用说所有其他标记结构。
如果您的语言是在Web浏览器中运行的JavaScript,则没有充分的理由尝试,因为浏览器已经很好地将您的文档解析为Element对象和Text节点。不要让浏览器将所有这些文档对象重新序列化为新的HTML,破解HTML并将其写回innerHTML
!除了速度慢之外,这将破坏所有现有内容以用新对象替换它,这会产生丢失所有不可序列化信息的副作用,如表单字段值,JavaScript引用,expandos和事件处理程序。
您可以简单地浏览要查看替换元素的所有Text节点。琐碎的例子:
function replaceText(element, pattern, replacement) {
for (var childi= element.childNodes.length; childi-->0;) {
var child= element.childNodes[childi];
if (child.nodeType==1) # Node.ELEMENT_NODE
replaceText(child, pattern, replacement);
else if (child.nodeType==3) # Node.TEXT_NODE
child.data= child.data.replace(pattern, replacement);
}
}
replaceText($('#foo')[0], /\bfoo\b/gi, 'bar');
答案 1 :(得分:1)
如果将正则表达式的结果保存为匹配对象,请执行以下操作:
var regex = new RegExp('(>[\\w\\s]*)\\bfoo\\b([\\w\\s]*<)',"ig");
var mystring = "<span id=foo> blah blah foo blah foo blah </span>";
var match = regex.exec(mystring);
您可以使用另一个更简单的正则表达式来再次查看匹配的字符串,以查找多次出现的“foo”。匹配的字符串将位于match[0]
。
答案 2 :(得分:1)
您好我正在使用jquery进行reg ex替换,以便在我自己的网站上加粗所有p标签的所有首字母。 我认为代码也可以回答您的问题。
<!DOCTYPE html>
<html>
<head>
<title>JQ Replace foo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
#foo {color:#00c;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('* #foo').each(function(){ //use star to select all elements with id=foo
var me = $(this);
me.html(me.text().replace(/foo/g,"bar")); // only change text 'foo' to 'bar' , not the html id=foo
});
});
</script>
</head>
<body>
<div id="foo"> blah blah foo blah foo blah </div>
<p id="foo"> blah blah foo blah foo blah </p>
<a id="foo"> blah blah foo blah foo blah </a>
</body>
</html>
简单但对我有用 John Guise(新西兰)
答案 3 :(得分:0)
以下似乎有效:
var str = "foo yea foot bfoo <span id=foo> blah blah foo blah foo blah </span> foo again <span id=foo>foo again</span>\n\nthis is foo again";
var r = new RegExp("\\bfoo\\b","ig");
str = str.replace(r, "'it works'");
alert(str);
答案 4 :(得分:0)
str = str.replace(/(>[^<]*<)/g, function(s, p1) {
return p1.replace(/\bfoo\b/g, '');
});
答案 5 :(得分:0)
我很困惑,为什么你不能这样做:
var replacement = $('#foo').html().replace(/\bfoo\b/g, '');
$('#foo').html(replacement);
答案 6 :(得分:0)
我试图以错误的方式做到这一点。这是我创建的解决方案,似乎工作得很好。它使用两个递归函数+ DOM遍历+正则表达式来创建正确的文本和跨节点。
function replaceText(element, pattern, syn_text) {
for (var childi = 0; childi < element.childNodes.length;childi++) {
var child= element2.childNodes[childi];
if (child.nodeType==1 && child.className!=syn_text){ //make sure we don't call function on newly created node
replaceText(child, pattern, syn_text); //call function on child
}
else if (child.nodeType==3){ //this is a text node, being processing with our regular expression
var str = child.data;
str = str.replace(pattern,function(s, p1,p2,p3) {
var parentNode = child.parentNode;
do_replace(s, p1,p2,p3,parentNode,pattern,syn_text);
parentNode.removeChild(child); //delete old child from parent node. we've replaced it with new nodes at this point
});
}
}}
function do_replace(s, p1,p2,p3,parentNode,pattern,syn_text) {
if(p1.length>0){ //this might not be necessary
//create textnode
var text_node = document.createTextNode(p1);
parentNode.appendChild(text_node);
}
if(p2.length > 0){ //create a span + next_node for the highlighting code
spanTag = document.createElement("span");
spanTag.id = "SString" + id++;
spanTag.className = syn_text;
spanTag.innerHTML = p2;
parentNode.appendChild(spanTag);
}
if(p3.length > 0){
//test to see if p3 contains another instance of our string.
if(pattern.test(p3)){ //if there is a instance of our text string in the third part of the string, call function again
p3.replace(pattern,function(s, p1,p2,p3) {
//debugger;
do_replace(s, p1,p2,p3,parentNode,pattern);
return;
});
}
else{ //otherwise, it's just a plain textnode, so just reinsert it.
var text_nodep3 = document.createTextNode(p3);
parentNode.appendChild(text_nodep3);
return;
}
}
else{ //does this do anything?
return;
}
return}
此函数调用如下:
syn_highlight = "highlight_me"; //class to signify highlighting
pattern = new RegExp('([\\w\\W]*?)\\b('+ searchTerm + '[\\w]*)\\b([\\w\\W]*)',"ig");
replaceText($('#BodyContent')[0],pattern,syn_highlight);