0

Let's say for example I have this simple string

let str = '5+81+3+16+42'

Now if I want to capture each plus sign with both numbers around it.

My attempt was as follows:

let matches = str.match(/\d+\+\d+/g);

What I got with that is:

['5+81', '3+16']

Why is it not matching the cases between?

['5+81', '81+3', '3+16', '16+42']

4 Answers4

3

Your regex has to fulfill the whole pattern which is \d+\+\d+. It will first match 5+81, then the next character is a + which the pattern can not match because it should start with a digit. Then it can match 3+16 but it can not match the following +42 anymore given you ['5+81', '3+16'] as the matches.

Without a regex, you might use split and a for loop and check if the next value exists in the parts array:

let str = '5+81+3+16+42'
let parts = str.split('+');
for (let i = 0; i < parts.length; i++) {
  if (undefined !== parts[i + 1]) {
    console.log(parts[i] + '+' + parts[i + 1]);
  }
}

When using more a recent version of Chrome which supports lookbehinds, you might use lookarounds with capturing groups:

(?<=(\d+))(\+)(?=(\d+))

See the regex demo

const regex = /(?<=(\d+))(\+)(?=(\d+))/g;
const str = `5+81+3+16+42`;
let m;

while ((m = regex.exec(str)) !== null) {
  if (m.index === regex.lastIndex) {
    regex.lastIndex++;
  }
  console.log(m[1] + m[2] + m[3]);
}
The fourth bird
  • 127,136
  • 16
  • 45
  • 63
2

When the regular expression engine completes one iteration of a match, it "consumes" the characters from the source string. The first match of 5+81 leaves the starting point for the next match at the + sign after 81, so the next match for the expression begins at the 3.

Pointy
  • 389,373
  • 58
  • 564
  • 602
2

Split string by + delimiter and use .reduce() to create new array contain target result.

let str = '5+81+3+16+42';
let arr = str.split('+').reduce((tot, num, i, arr) => { 
  i+1 < arr.length ? tot.push(num+"+"+arr[i+1]) : '';
  return tot; 
}, []);
console.log(arr);
Mohammad
  • 20,339
  • 15
  • 51
  • 79
2

You can do it using split and reduce without making things complex with regex.

let str = '5+81+3+16+42';
const array = str.split('+');

const splited = []
array.reduce((a, b) => {
  splited.push(a+'+'+b)
  return b
})

console.log(splited);
Always Sunny
  • 32,751
  • 7
  • 52
  • 86