Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
tl;dr Although it can be done with regex (and work for "most" cases), I still prefer to use a parser. Long answer I'd use something such as DOMParser to do the job: let validTags = ['p', 'span', 'b...
Answer
#4: Post edited
- # tl;dr
- Although it can be done with regex (and work for "most" cases), I still prefer to use a *parser*.
- # Long answer
- I'd use something such as [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to do the job:
- ```javascript
- let validTags = ['p', 'span', 'br', 'i', 'b', 'u'];
- let validAttribs = ['style', 'href'];
- function validHtml(string) {
- let domparser = new DOMParser();
- let doc = domparser.parseFromString(string, 'application/xml');
- for (const node of doc.querySelectorAll('*')) {
- if (! validTags.includes(node.nodeName)) return false;
- for (const attr of node.attributes) {
- if (! validAttribs.includes(attr.name)) return false;
- }
- }
- return true;
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // false
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // false
- ```
- With this, not only I can easily update the rules (change the arrays of valid tags and attributes), but also validate the HTML itself - [according to the docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Error_handling), when the string is invalid, `parseFromString` returns an error document:
- ```xml
- <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
- (error description)
- <sourcetext>(a snippet of the source XML)</sourcetext>
- </parsererror>
- ```
- So, when checking it in the `for` loop, it will enter the first `if` (because the tag `parseerror` is not in the array of valid tags) and it'll return `false` as well.
- ---
- You told you don't care if the HTML is valid, but even without that restriction, doing it with regex is - IMO - much worse. I could think of something like this:
- ```javascript
- function validHtml(string) {
- // check if it has invalid tag
- let tags = /<(?!\b([piu]|span|br?)\b)[^>]*>/;
- // check if tag is valid, but with an invalid attribute
- let attributes = /<\b([piu]|span|br?)\b[^>\w]*(?!\b(href|style)\b=[^>]*)\w[^>]*>/;
- return (! tags.test(string)) || (! attributes.test(string));
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // true
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // true
- ```
- The only difference between this and the first example is the first and the last cases. In the first case, the HTML is invalid, although it has all the valid tags (so the regex says it's valid). And in the last case, the string is not even HTML at all, but the regex also says it's valid - and this also happens with strings like `' '` and `'!@#$%¨&*'`.
- But the problem here is - IMO - how easy/hard is to read, understand and maintain each one of the options. I think the first one with `DOMParser` is much easier - and you have more control over the structure (having DOM nodes, you can easily check whatever information they have, making it easier to change the criteria - such as check attribute values, comments, text nodes and so on).
- And I haven't done extensive tests with those regexes, so I'm pretty sure there could be lots of corner cases that they don't catch - which are already handled by a HTML parser.
Regarding overhead, regex also has its own. If performance is an issue, you should benchmark it anyway. But I believe you should also consider how easy it is to maitain the code - IMO, the regexes above are not trivial to understand.- My conclusion is that using regex might work, but I wouldn't recommend it as "the best way".
- # tl;dr
- Although it can be done with regex (and work for "most" cases), I still prefer to use a *parser*.
- # Long answer
- I'd use something such as [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to do the job:
- ```javascript
- let validTags = ['p', 'span', 'br', 'i', 'b', 'u'];
- let validAttribs = ['style', 'href'];
- function validHtml(string) {
- let domparser = new DOMParser();
- let doc = domparser.parseFromString(string, 'application/xml');
- for (const node of doc.querySelectorAll('*')) {
- if (! validTags.includes(node.nodeName)) return false;
- for (const attr of node.attributes) {
- if (! validAttribs.includes(attr.name)) return false;
- }
- }
- return true;
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // false
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // false
- ```
- With this, not only I can easily update the rules (change the arrays of valid tags and attributes), but also validate the HTML itself - [according to the docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Error_handling), when the string is invalid, `parseFromString` returns an error document:
- ```xml
- <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
- (error description)
- <sourcetext>(a snippet of the source XML)</sourcetext>
- </parsererror>
- ```
- So, when checking it in the `for` loop, it will enter the first `if` (because the tag `parseerror` is not in the array of valid tags) and it'll return `false` as well.
- ---
- You told you don't care if the HTML is valid, but even without that restriction, doing it with regex is - IMO - much worse. I could think of something like this:
- ```javascript
- function validHtml(string) {
- // check if it has invalid tag
- let tags = /<(?!\b([piu]|span|br?)\b)[^>]*>/;
- // check if tag is valid, but with an invalid attribute
- let attributes = /<\b([piu]|span|br?)\b[^>\w]*(?!\b(href|style)\b=[^>]*)\w[^>]*>/;
- return (! tags.test(string)) || (! attributes.test(string));
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // true
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // true
- ```
- The only difference between this and the first example is the first and the last cases. In the first case, the HTML is invalid, although it has all the valid tags (so the regex says it's valid). And in the last case, the string is not even HTML at all, but the regex also says it's valid - and this also happens with strings like `' '` and `'!@#$%¨&*'`.
- But the problem here is - IMO - how easy/hard is to read, understand and maintain each one of the options. I think the first one with `DOMParser` is much easier - and you have more control over the structure (having DOM nodes, you can easily check whatever information they have, making it easier to change the criteria - such as check attribute values, comments, text nodes and so on).
- And I haven't done extensive tests with those regexes, so I'm pretty sure there could be lots of corner cases that they don't catch - which are already handled by a HTML parser.
- Regarding overhead, regex also has its own. If performance is an issue, you should benchmark it anyway. But I believe you should also consider how easy it is to maintain the code - IMO, the regexes above are not trivial to understand.
- My conclusion is that using regex might work, but I wouldn't recommend it as "the best way".
#3: Post edited
- # tl;dr
- Although it can be done with regex (and work for "most" cases), I still prefer to use a *parser*.
- # Long answer
- I'd use something such as [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to do the job:
- ```javascript
- let validTags = ['p', 'span', 'br', 'i', 'b', 'u'];
- let validAttribs = ['style', 'href'];
- function validHtml(string) {
- let domparser = new DOMParser();
- let doc = domparser.parseFromString(string, 'application/xml');
- for (const node of doc.querySelectorAll('*')) {
- if (! validTags.includes(node.nodeName)) return false;
- for (const attr of node.attributes) {
- if (! validAttribs.includes(attr.name)) return false;
- }
- }
- return true;
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // false
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // false
- ```
- With this, not only I can easily update the rules (change the arrays of valid tags and attributes), but also validate the HTML itself - [according to the docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Error_handling), when the string is invalid, `parseFromString` returns an error document:
- ```xml
- <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
- (error description)
- <sourcetext>(a snippet of the source XML)</sourcetext>
- </parsererror>
- ```
- So, when checking it in the `for` loop, it will enter the first `if` (because the tag `parseerror` is not in the array of valid tags) and it'll return `false` as well.
- ---
- You told you don't care if the HTML is valid, but even without that restriction, doing it with regex is - IMO - much worse. I could think of something like this:
- ```javascript
- function validHtml(string) {
- // check if it has invalid tag
- let tags = /<(?!\b([piu]|span|br?)\b)[^>]*>/;
- // check if tag is valid, but with an invalid attribute
- let attributes = /<\b([piu]|span|br?)\b[^>\w]*(?!\b(href|style)\b=[^>]*)\w[^>]*>/;
- return (! tags.test(string)) || (! attributes.test(string));
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // true
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // true
- ```
The only difference between this and the first example is the first and the last cases. In the first case, the HTML is invalid, although it has all the valid tags (so the regex says it's valid). And in the last case, the string is not even HTML at all, but the regex also says it's valid.- But the problem here is - IMO - how easy/hard is to read, understand and maintain each one of the options. I think the first one with `DOMParser` is much easier - and you have more control over the structure (having DOM nodes, you can easily check whatever information they have, making it easier to change the criteria - such as check attribute values, comments, text nodes and so on).
- And I haven't done extensive tests with those regexes, so I'm pretty sure there could be lots of corner cases that they don't catch - which are already handled by a HTML parser.
- Regarding overhead, regex also has its own. If performance is an issue, you should benchmark it anyway. But I believe you should also consider how easy it is to maitain the code - IMO, the regexes above are not trivial to understand.
- My conclusion is that using regex might work, but I wouldn't recommend it as "the best way".
- # tl;dr
- Although it can be done with regex (and work for "most" cases), I still prefer to use a *parser*.
- # Long answer
- I'd use something such as [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to do the job:
- ```javascript
- let validTags = ['p', 'span', 'br', 'i', 'b', 'u'];
- let validAttribs = ['style', 'href'];
- function validHtml(string) {
- let domparser = new DOMParser();
- let doc = domparser.parseFromString(string, 'application/xml');
- for (const node of doc.querySelectorAll('*')) {
- if (! validTags.includes(node.nodeName)) return false;
- for (const attr of node.attributes) {
- if (! validAttribs.includes(attr.name)) return false;
- }
- }
- return true;
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // false
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // false
- ```
- With this, not only I can easily update the rules (change the arrays of valid tags and attributes), but also validate the HTML itself - [according to the docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Error_handling), when the string is invalid, `parseFromString` returns an error document:
- ```xml
- <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
- (error description)
- <sourcetext>(a snippet of the source XML)</sourcetext>
- </parsererror>
- ```
- So, when checking it in the `for` loop, it will enter the first `if` (because the tag `parseerror` is not in the array of valid tags) and it'll return `false` as well.
- ---
- You told you don't care if the HTML is valid, but even without that restriction, doing it with regex is - IMO - much worse. I could think of something like this:
- ```javascript
- function validHtml(string) {
- // check if it has invalid tag
- let tags = /<(?!\b([piu]|span|br?)\b)[^>]*>/;
- // check if tag is valid, but with an invalid attribute
- let attributes = /<\b([piu]|span|br?)\b[^>\w]*(?!\b(href|style)\b=[^>]*)\w[^>]*>/;
- return (! tags.test(string)) || (! attributes.test(string));
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // true
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // true
- ```
- The only difference between this and the first example is the first and the last cases. In the first case, the HTML is invalid, although it has all the valid tags (so the regex says it's valid). And in the last case, the string is not even HTML at all, but the regex also says it's valid - and this also happens with strings like `' '` and `'!@#$%¨&*'`.
- But the problem here is - IMO - how easy/hard is to read, understand and maintain each one of the options. I think the first one with `DOMParser` is much easier - and you have more control over the structure (having DOM nodes, you can easily check whatever information they have, making it easier to change the criteria - such as check attribute values, comments, text nodes and so on).
- And I haven't done extensive tests with those regexes, so I'm pretty sure there could be lots of corner cases that they don't catch - which are already handled by a HTML parser.
- Regarding overhead, regex also has its own. If performance is an issue, you should benchmark it anyway. But I believe you should also consider how easy it is to maitain the code - IMO, the regexes above are not trivial to understand.
- My conclusion is that using regex might work, but I wouldn't recommend it as "the best way".
#2: Post edited
- # tl;dr
- Although it can be done with regex (and work for "most" cases), I still prefer to use a *parser*.
- # Long answer
- I'd use something such as [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to do the job:
- ```javascript
- let validTags = ['p', 'span', 'br', 'i', 'b', 'u'];
- let validAttribs = ['style', 'href'];
- function validHtml(string) {
- let domparser = new DOMParser();
- let doc = domparser.parseFromString(string, 'application/xml');
- for (const node of doc.querySelectorAll('*')) {
- if (! validTags.includes(node.nodeName)) return false;
- for (const attr of node.attributes) {
- if (! validAttribs.includes(attr.name)) return false;
- }
- }
- return true;
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // false
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- ```
- With this, not only I can easily update the rules (change the arrays of valid tags and attributes), but also validate the HTML itself - [according to the docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Error_handling), when the string is invalid, `parseFromString` returns an error document:
- ```xml
- <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
- (error description)
- <sourcetext>(a snippet of the source XML)</sourcetext>
- </parsererror>
- ```
- So, when checking it in the `for` loop, it will enter the first `if` (because the tag `parseerror` is not in the array of valid tags) and it'll return `false` as well.
- ---
- You told you don't care if the HTML is valid, but even without that restriction, doing it with regex is - IMO - much worse. I could think of something like this:
- ```javascript
- function validHtml(string) {
- // check if it has invalid tag
- let tags = /<(?!\b([piu]|span|br?)\b)[^>]*>/;
- // check if tag is valid, but with an invalid attribute
- let attributes = /<\b([piu]|span|br?)\b[^>\w]*(?!\b(href|style)\b=[^>]*)\w[^>]*>/;
- return (! tags.test(string)) || (! attributes.test(string));
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // true
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- ```
The only difference between this and the first example is the first case: the HTML is invalid, although it has all the valid tags.- But the problem here is - IMO - how easy/hard is to read, understand and maintain each one of the options. I think the first one with `DOMParser` is much easier - and you have more control over the structure (having DOM nodes, you can easily check whatever information they have, making it easier to change the criteria - such as check attribute values, comments, text nodes and so on).
- And I haven't done extensive tests with those regexes, so I'm pretty sure there could be lots of corner cases that they don't catch - which are already handled by a HTML parser.
- Regarding overhead, regex also has its own. If performance is an issue, you should benchmark it anyway. But I believe you should also consider how easy it is to maitain the code - IMO, the regexes above are not trivial to understand.
- My conclusion is that using regex might work, but I wouldn't recommend it as "the best way".
- # tl;dr
- Although it can be done with regex (and work for "most" cases), I still prefer to use a *parser*.
- # Long answer
- I'd use something such as [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to do the job:
- ```javascript
- let validTags = ['p', 'span', 'br', 'i', 'b', 'u'];
- let validAttribs = ['style', 'href'];
- function validHtml(string) {
- let domparser = new DOMParser();
- let doc = domparser.parseFromString(string, 'application/xml');
- for (const node of doc.querySelectorAll('*')) {
- if (! validTags.includes(node.nodeName)) return false;
- for (const attr of node.attributes) {
- if (! validAttribs.includes(attr.name)) return false;
- }
- }
- return true;
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // false
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // false
- ```
- With this, not only I can easily update the rules (change the arrays of valid tags and attributes), but also validate the HTML itself - [according to the docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Error_handling), when the string is invalid, `parseFromString` returns an error document:
- ```xml
- <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">
- (error description)
- <sourcetext>(a snippet of the source XML)</sourcetext>
- </parsererror>
- ```
- So, when checking it in the `for` loop, it will enter the first `if` (because the tag `parseerror` is not in the array of valid tags) and it'll return `false` as well.
- ---
- You told you don't care if the HTML is valid, but even without that restriction, doing it with regex is - IMO - much worse. I could think of something like this:
- ```javascript
- function validHtml(string) {
- // check if it has invalid tag
- let tags = /<(?!\b([piu]|span|br?)\b)[^>]*>/;
- // check if tag is valid, but with an invalid attribute
- let attributes = /<\b([piu]|span|br?)\b[^>\w]*(?!\b(href|style)\b=[^>]*)\w[^>]*>/;
- return (! tags.test(string)) || (! attributes.test(string));
- }
- console.log(validHtml('<p></span></p>>><br href="./></span>')); // true
- console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false
- console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true
- console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false
- console.log(validHtml('abc')); // true
- ```
- The only difference between this and the first example is the first and the last cases. In the first case, the HTML is invalid, although it has all the valid tags (so the regex says it's valid). And in the last case, the string is not even HTML at all, but the regex also says it's valid.
- But the problem here is - IMO - how easy/hard is to read, understand and maintain each one of the options. I think the first one with `DOMParser` is much easier - and you have more control over the structure (having DOM nodes, you can easily check whatever information they have, making it easier to change the criteria - such as check attribute values, comments, text nodes and so on).
- And I haven't done extensive tests with those regexes, so I'm pretty sure there could be lots of corner cases that they don't catch - which are already handled by a HTML parser.
- Regarding overhead, regex also has its own. If performance is an issue, you should benchmark it anyway. But I believe you should also consider how easy it is to maitain the code - IMO, the regexes above are not trivial to understand.
- My conclusion is that using regex might work, but I wouldn't recommend it as "the best way".
#1: Initial revision
# tl;dr Although it can be done with regex (and work for "most" cases), I still prefer to use a *parser*. # Long answer I'd use something such as [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to do the job: ```javascript let validTags = ['p', 'span', 'br', 'i', 'b', 'u']; let validAttribs = ['style', 'href']; function validHtml(string) { let domparser = new DOMParser(); let doc = domparser.parseFromString(string, 'application/xml'); for (const node of doc.querySelectorAll('*')) { if (! validTags.includes(node.nodeName)) return false; for (const attr of node.attributes) { if (! validAttribs.includes(attr.name)) return false; } } return true; } console.log(validHtml('<p></span></p>>><br href="./></span>')); // false console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false ``` With this, not only I can easily update the rules (change the arrays of valid tags and attributes), but also validate the HTML itself - [according to the docs](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Error_handling), when the string is invalid, `parseFromString` returns an error document: ```xml <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml"> (error description) <sourcetext>(a snippet of the source XML)</sourcetext> </parsererror> ``` So, when checking it in the `for` loop, it will enter the first `if` (because the tag `parseerror` is not in the array of valid tags) and it'll return `false` as well. --- You told you don't care if the HTML is valid, but even without that restriction, doing it with regex is - IMO - much worse. I could think of something like this: ```javascript function validHtml(string) { // check if it has invalid tag let tags = /<(?!\b([piu]|span|br?)\b)[^>]*>/; // check if tag is valid, but with an invalid attribute let attributes = /<\b([piu]|span|br?)\b[^>\w]*(?!\b(href|style)\b=[^>]*)\w[^>]*>/; return (! tags.test(string)) || (! attributes.test(string)); } console.log(validHtml('<p></span></p>>><br href="./></span>')); // true console.log(validHtml('<p onclick="alert(\'hi\')"></p>')); // false console.log(validHtml('<p style="padding: 2px">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // true console.log(validHtml('<p class="whatever">Lorem <span>ipsum <b>dolor</b> sit <u>amet</u></span></p>')); // false ``` The only difference between this and the first example is the first case: the HTML is invalid, although it has all the valid tags. But the problem here is - IMO - how easy/hard is to read, understand and maintain each one of the options. I think the first one with `DOMParser` is much easier - and you have more control over the structure (having DOM nodes, you can easily check whatever information they have, making it easier to change the criteria - such as check attribute values, comments, text nodes and so on). And I haven't done extensive tests with those regexes, so I'm pretty sure there could be lots of corner cases that they don't catch - which are already handled by a HTML parser. Regarding overhead, regex also has its own. If performance is an issue, you should benchmark it anyway. But I believe you should also consider how easy it is to maitain the code - IMO, the regexes above are not trivial to understand. My conclusion is that using regex might work, but I wouldn't recommend it as "the best way".