1

I want to test whether a string is 8 digits or the same number can be divided into 4 parts separated by a -.

I have a regex that does work:

/^\d{2}([-]?)(\d{2})\1\d{2}\1\d{2}$/

And I can prove:

/^\d{2}([-]?)(\d{2})\1\d{2}\1\d{2}$/.test('12345678'); // true
/^\d{2}([-]?)(\d{2})\1\d{2}\1\d{2}$/.test('12-34-56-78');  // true
/^\d{2}([-]?)(\d{2})\1\d{2}\1\d{2}$/.test('12-45-7810'); // false
/^\d{2}([-]?)(\d{2})\1\d{2}\1\d{2}$/.text('-12-45-78-10'); //false

I would have liked to have created a group from \d{2} but I tried this:

/^(\d{2})([-]?)\1\2\1\2\1$/

But it does not match anything.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
dagda1
  • 26,856
  • 59
  • 237
  • 450

3 Answers3

1

You can write even shorter: ^\d\d(-\d\d){3}$|^\d{8}$

Hegel F.
  • 125
  • 6
1

You cannot make backrefernces (references to actual values captured with group patterns) work as subroutines (constructs "repeating" some group patterns, not the actual captured values).

You can only define pattern parts and use them to build longer patterns:

const n = "\\d{2}";
const h = "-?";
const rx = new RegExp(`^${n}(?:${h}${n}){3}$`);
console.log(rx.source); // ^\d{2}(?:-?\d{2}){3}$
// ES5:
// var rx = new RegExp("^" + n + "(?:" + h + n+ "){3}$");
 
const strs = ['12345678', '12-34-56-78', '12-45-7810', '-12-45-78-10'];
for (let s of strs) {
 console.log(s, "=>", rx.test(s));
}
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

Have you tried:

const r = new RegExp(/^-?\d{2}-?\d{2}-?\d{2}-?\d{2}$/);
console.log(r.test("12345678")); // true
console.log(r.test("12-34-56-78")); // true
console.log(r.test("12-45-7810")); // true
console.log(r.test("-12-45-78-10")); // true

This works on my end.

edmond
  • 1,432
  • 2
  • 15
  • 19