I need to change needed inside only a specific tag.
我需要在特定标签内部进行更改。
for instance,
"this is first <a>this is second</a> this is third"
here, I want to find only second "is". I can find whole text between by /(<a)[\S\s]*?(<\/a>)/gi
, but I dont know how I can find "is" inside this regex
在这里,我想找到第二个“是”。我可以在/( )/ gi之间找到全文,但我不知道我怎么能在这个正则表达式中找到“是” )[\>
1 个解决方案
#1
0
I propose not using a regular expression here, as the problem is a bit too complex and while it's possible to do using a regex it will not be pretty and you can miss some edge cases.
我建议不要在这里使用正则表达式,因为问题有点过于复杂,虽然可以使用正则表达式,但它不会很漂亮,你可能会错过一些边缘情况。
So, here is how I would do it
那么,我就是这样做的
var input = "this is first <a>this is second</a> this is third";
//this isn't truly using a regex - it's a very small part of the solution, hence a very small regex. It will match any word "is" but not "this"
var regex =/\bis\b/ig;
//this is a new unattached element that will be used to leverage the DOM parsing of the browser
var scratchPad = document.createElement("div");
//this will set the content of the <div> tag and it will be parsed as HTML
scratchPad.innerHTML = input;
//no need to parse the tags manually - we can just do it like this
var allTags = Array.from(scratchPad.getElementsByTagName("a"));
//iterate and modify the elements in place
allTags.forEach(function(el) {
el.innerHTML = el.innerHTML.replace(regex, "!FOO!")
});
//see the results
console.log(scratchPad.innerHTML);
This is lengthy but it is to illustrate what happens.
这很冗长,但它是为了说明会发生什么。
Here is a more realistic example of how it might be used
这是一个更实际的例子,说明如何使用它
function replacer(input, replaceWhat, replaceWith, inTag) {
var regex = new RegExp("\\b" + replaceWhat + "\\b", "ig");
var scratchPad = document.getElementById("_replacingDiv");
//if not there, create it and attach it, so it's available next time
if (!scratchPad) {
scratchPad = document.createElement("div");
scratchPad.id = "_replacingDiv";
scratchPad.hidden = true;
document.body.appendChild(scratchPad);
}
scratchPad.innerHTML = input;
var tags = scratchPad.getElementsByTagName(inTag);
Array.prototype.forEach.call(tags, function(el) {
el.innerHTML = el.innerHTML.replace(regex, replaceWith);
});
return scratchPad.innerHTML;
}
var inputSimple = "this is first <a>this is second</a> this is third";
var inputComplex = "this is first <a>this is second</a> \n"+
"this is third <a>this is fourth</a> \n"+
"this is fifth <a>no match sixth</a> \n"+
"this isn't matched seventh <a>this isn't matched eighth</a> \n"+
"mutltiple is is example ninth <a>multiple is is example tenth </a>";
console.log(replacer(inputSimple, "is", "!FOO!", "a"));
console.log(replacer(inputComplex, "is", "!FOO!", "a"));
This should not be taken as the final form of the function but from here, you can tailor it to your needs. Here are some things that might need changing:
这不应该被视为功能的最终形式,但是从这里开始,您可以根据自己的需要进行定制。以下是一些可能需要更改的内容:
- One obvious improvement is to pass a configuration object, although you might also need less parameters in which case, it won't be as needed
- Do you want to consider any match valid or only words? Right now it only handles words, although if you want to replace it that will also be replaced inside it's - that might or might not suit your needs.
- If the input is driven by the user then this specific approach might be vulnerable as it will be interpreting untrusted code. In this case you can use a sandboxed iframe as
scratchPad
instead and this will prevent any malicious code from being ran. However, you will still need to deal with the output securely. - if the replacement driven by the user the same applies as above.
- this will only really work if the tags you are replacing do not have other tags nested in them. For example, if you want to replace every occurrence of
foo
in aspan
but that tag contains a nesteda
. If that's the case, it's up to you to determine what would exactly would happen - whether the inner tags will be considered or skipped. Beware not to replace anything in side any HTML, say, if there is<a class="foo">
一个显而易见的改进是传递配置对象,尽管您可能还需要较少的参数,在这种情况下,它将不是必需的
你想考虑任何匹配有效或只有单词吗?现在它只处理单词,虽然如果你想要替换它也会被替换它 - 可能会或可能不适合你的需要。
如果输入是由用户驱动的,那么这种特定的方法可能会受到攻击,因为它将解释不受信任的代码。在这种情况下,您可以使用沙盒iframe代替scratchPad,这样可以防止任何恶意代码被运行。但是,您仍然需要安全地处理输出。
如果由用户驱动的替换同样适用于上述。
只有当你要替换的标签没有嵌套在其中的其他标签时,这才会真正起作用。例如,如果要替换span中每次出现的foo,但该标记包含嵌套的a。如果是这种情况,由您自行决定究竟会发生什么 - 是否会考虑或跳过内部标记。请注意,如果有,请注意不要替换任何HTML中的任何内容
#1
0
I propose not using a regular expression here, as the problem is a bit too complex and while it's possible to do using a regex it will not be pretty and you can miss some edge cases.
我建议不要在这里使用正则表达式,因为问题有点过于复杂,虽然可以使用正则表达式,但它不会很漂亮,你可能会错过一些边缘情况。
So, here is how I would do it
那么,我就是这样做的
var input = "this is first <a>this is second</a> this is third";
//this isn't truly using a regex - it's a very small part of the solution, hence a very small regex. It will match any word "is" but not "this"
var regex =/\bis\b/ig;
//this is a new unattached element that will be used to leverage the DOM parsing of the browser
var scratchPad = document.createElement("div");
//this will set the content of the <div> tag and it will be parsed as HTML
scratchPad.innerHTML = input;
//no need to parse the tags manually - we can just do it like this
var allTags = Array.from(scratchPad.getElementsByTagName("a"));
//iterate and modify the elements in place
allTags.forEach(function(el) {
el.innerHTML = el.innerHTML.replace(regex, "!FOO!")
});
//see the results
console.log(scratchPad.innerHTML);
This is lengthy but it is to illustrate what happens.
这很冗长,但它是为了说明会发生什么。
Here is a more realistic example of how it might be used
这是一个更实际的例子,说明如何使用它
function replacer(input, replaceWhat, replaceWith, inTag) {
var regex = new RegExp("\\b" + replaceWhat + "\\b", "ig");
var scratchPad = document.getElementById("_replacingDiv");
//if not there, create it and attach it, so it's available next time
if (!scratchPad) {
scratchPad = document.createElement("div");
scratchPad.id = "_replacingDiv";
scratchPad.hidden = true;
document.body.appendChild(scratchPad);
}
scratchPad.innerHTML = input;
var tags = scratchPad.getElementsByTagName(inTag);
Array.prototype.forEach.call(tags, function(el) {
el.innerHTML = el.innerHTML.replace(regex, replaceWith);
});
return scratchPad.innerHTML;
}
var inputSimple = "this is first <a>this is second</a> this is third";
var inputComplex = "this is first <a>this is second</a> \n"+
"this is third <a>this is fourth</a> \n"+
"this is fifth <a>no match sixth</a> \n"+
"this isn't matched seventh <a>this isn't matched eighth</a> \n"+
"mutltiple is is example ninth <a>multiple is is example tenth </a>";
console.log(replacer(inputSimple, "is", "!FOO!", "a"));
console.log(replacer(inputComplex, "is", "!FOO!", "a"));
This should not be taken as the final form of the function but from here, you can tailor it to your needs. Here are some things that might need changing:
这不应该被视为功能的最终形式,但是从这里开始,您可以根据自己的需要进行定制。以下是一些可能需要更改的内容:
- One obvious improvement is to pass a configuration object, although you might also need less parameters in which case, it won't be as needed
- Do you want to consider any match valid or only words? Right now it only handles words, although if you want to replace it that will also be replaced inside it's - that might or might not suit your needs.
- If the input is driven by the user then this specific approach might be vulnerable as it will be interpreting untrusted code. In this case you can use a sandboxed iframe as
scratchPad
instead and this will prevent any malicious code from being ran. However, you will still need to deal with the output securely. - if the replacement driven by the user the same applies as above.
- this will only really work if the tags you are replacing do not have other tags nested in them. For example, if you want to replace every occurrence of
foo
in aspan
but that tag contains a nesteda
. If that's the case, it's up to you to determine what would exactly would happen - whether the inner tags will be considered or skipped. Beware not to replace anything in side any HTML, say, if there is<a class="foo">
一个显而易见的改进是传递配置对象,尽管您可能还需要较少的参数,在这种情况下,它将不是必需的
你想考虑任何匹配有效或只有单词吗?现在它只处理单词,虽然如果你想要替换它也会被替换它 - 可能会或可能不适合你的需要。
如果输入是由用户驱动的,那么这种特定的方法可能会受到攻击,因为它将解释不受信任的代码。在这种情况下,您可以使用沙盒iframe代替scratchPad,这样可以防止任何恶意代码被运行。但是,您仍然需要安全地处理输出。
如果由用户驱动的替换同样适用于上述。
只有当你要替换的标签没有嵌套在其中的其他标签时,这才会真正起作用。例如,如果要替换span中每次出现的foo,但该标记包含嵌套的a。如果是这种情况,由您自行决定究竟会发生什么 - 是否会考虑或跳过内部标记。请注意,如果有,请注意不要替换任何HTML中的任何内容