0

I have this regex that should match when there's two numbers in brackets /(P|C\(\d+\,{0,1}\s*\d+\))/g for example:

C(1, 2) or P(2 3) //expected to match

C(43) or C(43, ) // expect not to match

but it also matches the ones with only 1 number, how can i fix it?

Peter Thoeny
  • 7,379
  • 1
  • 10
  • 20
yeezy
  • 15
  • 2

4 Answers4

2

You have a couple of issues. Firstly, your regex will match either P on its own or C followed by numbers in parentheses; you should replace P|C with [PC] (you could use (?:P|C) but [PC] is more performant, see this Q&A). Secondly, since your regex makes both the , and spaces optional, it can match 43 without an additional number (the 4 matches the first \d+ and the 3 the second \d+). You need to force the string to either include a , or at least one space between the numbers. You can do that with this regex:

[PC]\(\d+[ ,]\s*\d+\)

Demo on regex101

Nick
  • 138,499
  • 22
  • 57
  • 95
1

Try this regex

[PC]\(\d+(?:,| +) *\d+\)

Click for Demo

Explanation:

  • [PC]\( - matches either P( or C(
  • \d+ - matches 1+ digits
  • (?:,| +) - matches either a , or 1+ spaces
  • *\d+ - matches 0+ spaces followed by 1+ digits
  • \) - matches )
Gurmanjot Singh
  • 10,224
  • 2
  • 19
  • 43
1

You can relax the separator between the numbers by allowing any combination of command and space by using \d[,\s]+\d. Test case:

const regex = /[PC]\(\d+[,\s]+\d+\)/g;
[
  'C(1, 2) or P(2 3)',
  'C(43) or C(43, )'
].forEach(str => {
  let m = str.match(regex);
  console.log(str + ' ==> ' + JSON.stringify(m));
});

Output:

C(1, 2) or P(2 3) ==> ["C(1, 2)","P(2 3)"]
C(43) or C(43, ) ==> null
Peter Thoeny
  • 7,379
  • 1
  • 10
  • 20
0

Your regex should require the presence of at least one delimiting character between the numbers.

I suppose you want to get the numbers out of it separately, like in an array of numbers:

let tests = [
    "C(1, 2)",
    "P(2 3)",
    "C(43)",
    "C(43, )"
];

for (let test of tests) {
    console.log(
        test.match(/[PC]\((\d+)[,\s]+(\d+)\)/)?.slice(1)?.map(Number)
    );
}
trincot
  • 317,000
  • 35
  • 244
  • 286