You can work around the missing (*SKIP)(*FAIL)
support in JavaScript using capturing groups in the pattern and a bit of code logic.
Note the (*SKIP)(*FAIL)
verb sequence is explained in my YT video called “Skipping matches in specific contexts (with SKIP & FAIL verbs)”. You can also find a demo of JavaScript lookarounds for four different scenarions: extracting, replacing, removing and splitting.
Let’s adjust the code for the current question. Let’s assume word
always consists of word characters (digits, letters or underscores).
- Extracting: Capture the word into Group 1 and only extract Group 1 values:
const text = `foo <a href="https://stackoverflow.com/questions/71812772/foo.com">foo</a> foobar`;
const word = 'foo';
const regex = new RegExp(String.raw`<a .*?">|\b(${word})\b`, 'gi');
console.log(Array.from(text.matchAll(regex), x=>x[1]).filter(Boolean)); // => 1st word and `>foo<`
- Removing: Capture the context you need to keep into Group 1 and replace with a backreference to this group:
const text = `foo <a href="https://stackoverflow.com/questions/71812772/foo.com">foo</a> foobar`;
const word = 'foo';
const regex = new RegExp(String.raw`(<a .*?">)|\b${word}\b`, 'gi');
console.log(text.replace(regex, '$1')); // => <a href="https://stackoverflow.com/questions/71812772/foo.com"></a> foobar
- Replacing: Capture the context you need to keep into Group 1 and when it is used, replace with Group 1 value, else, replace with what you need in a callback function/arrow function used as the replacement argument:
const text = `foo <a href="https://stackoverflow.com/questions/71812772/foo.com">foo</a> foobar`;
const word = 'foo';
const regex = new RegExp(String.raw`(<a .*?">)|\b${word}\b`, 'gi');
console.log(text.replace(regex, (match, group1) => group1 || 'buz' ));
// => buz <a href="https://stackoverflow.com/questions/71812772/foo.com">buz</a> foobar
- Splitting: This is the most intricate scenario and it requires a bit more coding:
const text = `foo <a href="https://stackoverflow.com/questions/71812772/foo.com">foo</a> foobar`;
const word = 'foo';
const regex = new RegExp(String.raw`(<a .*?">)|\b${word}\b`, 'gi');
let m, res = [], offset = 0;
while (m = regex.exec(text)) { // If there is a match and...
if (m[1] === undefined) { // if Group 1 is not matched
// put the substring to result array
res.push(text.substring(offset, m.index)) // Put the value to array
offset = m.index + m[0].length // Set the new chunk start position
}
}
if (offset < text.length) { // If there is any more text after offset
res.push(text.substr(offset)) // add it to the result array
}
console.log(res);
// => ["", " <a href=\"foo.com\">", "</a> foobar"]