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
  • 154,723
  • 16
  • 55
  • 70
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
  • 405,095
  • 59
  • 585
  • 614
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
  • 21,175
  • 15
  • 55
  • 84
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);
A l w a y s S u n n y
  • 36,497
  • 8
  • 60
  • 103