-1

I'm trying to access all the capture groups to do a replace where we wrap the desired result in parentheses in a situation like this:

(See comments for desired result)


const text = 'nonsense nonsense relevant nonsense nonsense relevant nonsense nonsense';
const matcher = /(.*)(relevant)(.*)/gi // Not sure of my regex, since I can't figure out how to actually test it

let desiredResult; // 'nonsense nonsense (relevant) nonsense nonsense (relevant) nonsense nonsense'

I've seen the while loop method, but it's always only attending to a single capture group in the matcher, so I'm not able to glean what I need to understand from those examples

There probably is a duplicate of this question, but I've spent over an hour searching and haven't found it. Many apparently ask the same thing, but the multiple capture groups aspect seems to be ignored in all of them.

I'm open to other suggestions on how to do this, although my use case may become more complex, involving additional capture groups and operations, so I think this is the best approach. I'm aware of matchAll but I don't see how it solves my issue either. I want low level access to the indices, the matches, the whole shebang.

Slbox
  • 10,957
  • 15
  • 54
  • 106
  • 1
    Please provide the real life problem description. Replacing the match with itself in parentheses is as easy as `.replace(/word/g, '($&)')` – Wiktor Stribiżew Jul 01 '20 at 21:09

1 Answers1

0

Is there some reason why you can't use, or don't want to use, String.prototype.replace? This is exactly what it's intended to do: match and replace. exec only finds matches, without replacing.

*edit: since you say you want low level access, I'm changing my example to show how to use a callback function, and doing a little bit of fancy stuff, like taking the index of the match and adding it in square brackets after the parens. I also added white space captures before and after the matched word to show how multiple capturing groups are handled in this method.

const text = 'nonsense nonsense relevant nonsense nonsense relevant nonsense nonsense';
const matcher = /(\s+)(relevant)(\s+)/gi;

function cb(match, p1, p2, p3, i, fullTxt) {
  return p1 + '(' + p2 + ')['+i+']' + p3;
}
let desiredResult = text.replace(matcher, cb);
console.log(desiredResult);
David784
  • 7,031
  • 2
  • 22
  • 29
  • The parentheses replace is only a simple example. I'm trying to do complex multi-pass string manipulation and I can't understand how the `exec`/`while` loop work with multiple groups. People basically just say, "oh you can't use `match` to access capture groups with global regex" - but then every example using global regex uses a single capture group -_- – Slbox Jul 01 '20 at 21:08
  • 2
    There is no need to wrap the whole pattern with a capturing group, there is a `$&` backreference. – Wiktor Stribiżew Jul 01 '20 at 21:10
  • 1
    @Slbox edited to reflect your desire for "low level access." Using `replace` with a callback function is about as powerful as it gets. – David784 Jul 01 '20 at 21:21
  • 1
    Classic overthinking it situation. I use the replace callback all the time, but never the parameters after the match groups. ::facepalm:: – Slbox Jul 01 '20 at 21:22