Hi, I'm trying to check the format of the string with preg_match(). It has to accept only the
(zero or more of ,.* )(exactly 9 or 5 digit number)(1 or more of ,.* )(postive integer <= 4digits)(zero or more of ,.* ) format of strings.
Here, is what I tried:

((\s|\*|,|\.)*)(\d{4}|\d{10})((\s|\*|,|\.)+)(\d{1,4})((\s|\*|,|\.)*)
It is working with these numbers:

, *123456789, *51*, => true (exactly 9)
, .*12345, *51*, => true (exactly 5)
, .*123, *51*, => false (less than 5)
This is where I failed:

, .*1234567891011, *51*, => true (greater than 9), It is just considering the first 9 digits & ignoring others & returing true, but I should actually get false

, .*123456, *51*, => true (in between 5 &9), same here, considering first 5 digits & returning true.
Thanks for any help!

Member Avatar

Exact number of digits always trips me up, but I think you can do it with negative look-behind ?<! and negative look-ahead ?!:

(?<!\d)(\d{5}|\d{9})(?!\d)

Hey, I forgot to mention. I've tried that too. It is working when I simply use it for a number.
For eg: (?<!\d)(\d{5}|\d{9})(?!\d) works fine for 12345 or 123456789.
But, it isn't working fine when I consider the complete example.
((\s|\*|,|\.)*)(?<!\d)(\d{5}|\d{9})(?!\d)((\s|\*|,|\.)*) should match *., 12345.,.* and ,.123456789,.* but it isn't matching anything at all. Any Idea why?

Member Avatar

Don't you need to isolate the digit part with the neg looks by placing () around the whole lot?

Maybe this is overkill, but it may work with your use-cases - not tested thoroughly:

$pattern = "/[,\. \*]*((?<!\d)(\d{5}|\d{9})(?!\d))[,\. \*]+(\d{1,4})(?!\d)[,\. \*]*/";