Regex is notoriously the wrong tool for this job.
HTML is structured data that regex doesn't understand, which means you run into exactly the sort of issues you're having: for any non-trivial problem, the many allowed variations in HTML structure make it very difficult to parse using string manipulation techniques.
DOM methods are designed for manipulating that sort of data, so use them instead. The following will loop through every <a>
tag in the document, exclude those with no href attribute, those whose href begins with '#', or those with a name attribute, and set the 'target' attribute on the rest.
Array.from(document.getElementsByTagName('a')).forEach(function(a) {
if (
a.getAttribute("href") &&
a.getAttribute("href").indexOf('#') !==0 &&
a.getAttribute("name") === null
) {
a.setAttribute('target', '_blank'); // on links that already have this attribute this will do nothing
}
});
// Just to confirm:
console.log(document.getElementById('container').innerHTML)
<div id="container">
<a href="http://example.com">test</a>
<a href="#foo">test2</a>
<a href="http://example.com" target="_blank">test3</a>
<a name="foo">test4</a>
</div>