2

How can I get the same character to be part of two different matches?

e.g. I would like "abc".match(/ab|bc/g) to result in TWO matches -- one for the 'ab', which it will do in this scenario, but then also one for the 'bc'. In other words the 'b' character is part of both substrings I am looking for.

Ryan Scharfer
  • 505
  • 1
  • 3
  • 11

2 Answers2

1

You can't literally do that with a single match call. Once the character is consumed, it's consumed. However, Wiktor points to a duplicate (I should have realized) with an answer that does a very clever thing with repeated exec calls instead.

Another option, depending on the real-life situation, would be to get close enough that you can fix it with post-processing, using a positive lookahead assertion. We can say "only match a if it's immediately followed by b — but don't consume b". Then, if we have a results, we know they're really ab results (wouldn't have matched otherwise) and we can change them accordingly:

var result = "abc".match(/a(?=b)|bc/g);
if (result) {
    result = result.map(function(entry) {
        return entry === "a" ? "ab" : entry;
    });
}

Or with ES2015+:

let result = "abc".match(/a(?=b)|bc/g);
if (result) {
    result = result.map(e => e === "a" ? "ab" : e);
}

If the a part varies, you may be able to use other checks (such as entry.length === 1, or !entry.endsWith("b"), etc.) depending on the real data.

Live example (ES5 and earlier version assuming a):

var result = "abc".match(/a(?=b)|bc/g);
if (result) {
    result = result.map(function(entry) {
        return entry === "a" ? "ab" : entry;
    });
}
console.log(result);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

You will need to run two regular expressions. Once a character is "consumed" by a regular expression, it is not available anymore. ie. a character can only be matched once per regex.

Alternatively you can return 3 possible values, and based on return value determine the output. eg. /abc|ab|bc/g. This will return abc if both are present, then you can simply split on the terminal b, otherwise it will return either ab or bc if either are present.

AlienHoboken
  • 2,750
  • 20
  • 23