If underscore is not allowed at the begining or at the end and it is not allowed to have 2 or more consecutive underscore:
^(?:\d+_?){3}\d+$
If underscore is allowed at the begining or at the end:
^(?:\d*_?){3}\d*$
These regex match string that have 0 upto 3 underscore but not more.
See these 2 regexes in action:
$strings = array(
'123456',
'1_2_3_456',
'123_456',
'_123_456_',
'1_2_3_4_5_6',
'123___456',
);
$num = 3;
echo 'using "^(?:\d+_?){3}\d+$"',"\n";
foreach($strings as $string) {
if (preg_match("/^(?:\d+_?){".$num."}\d+$/", $string)) {
echo "OK: $string\n";
} else {
echo "KO: $string\n";
}
}
echo 'using "^(?:\d*_?){3}\d*$"',"\n";
foreach($strings as $string) {
if (preg_match("/^(?:\d*_?){".$num."}\d*$/", $string)) {
echo "OK: $string\n";
} else {
echo "KO: $string\n";
}
}
Output:
using "^(?:\d+_?){3}\d+$"
OK: 123456
OK: 1_2_3_456
OK: 123_456
KO: _123_456_
KO: 1_2_3_4_5_6
KO: 123___456
using "^(?:\d*_?){3}\d*$"
OK: 123456
OK: 1_2_3_456
OK: 123_456
OK: _123_456_
KO: 1_2_3_4_5_6
OK: 123___456