I am not a JavaScript person, and I couldn't get matchAll to work in a snippet here, nor in any other demo site. So, I used an old-fashioned regex iterator.
For one solution, we can try matching on the following regex pattern:
\bjob(?=s|\b)|(?<=\bjob)s\b
This will match job, when it appears either as a standalone word, or when it appears as a substring of jobs. The above alternation also matches the letter s when preceded by job. Then, as we iterate, we replace the s match with jobs, to get the final result.
var input = "The jobs report came out and it was a great job!";
var matches = [];
var counter = 0;
var re = /\bjob(?=s|\b)|(?<=\bjob)s\b/g;
var m;
do {
m = re.exec(input);
if (m) {
matches[counter++] = m[0] === "job" ? "job" : "jobs";
}
} while (m);
console.log(matches);
[job, jobs, job]? Something else?jobscount to thejobcount after the matching is finished.str.match(/jobs?/gi).flatMap(m => m.endsWith('s') ? [m, m.slice(0, -1)] : m)?[...str.match(/jobs/gi), ...str.match(/job/gi)]?