How to match exactly 3 digits in PHP's preg_match?

David picture David · Nov 25, 2012 · Viewed 47.3k times · Source

Lets say you have the following values:

123
1234
4567
12
1

I'm trying to right a preg_match which will only return true for '123' thus only matching if 3 digits. This is what I have, but it is also matching 1234 and 4567. I may have something after it too.

preg_match('/[0-9]{3}/',$number);

Answer

Martin Ender picture Martin Ender · Nov 25, 2012

What you need is anchors:

preg_match('/^[0-9]{3}$/',$number);

They signify the start and end of the string. The reason you need them is that generally regex matching tries to find any matching substring in the subject.

As rambo coder pointed out, the $ can also match before the last character in a string, if that last character is a new line. To changes this behavior (so that 456\n does not result in a match), use the D modifier:

preg_match('/^[0-9]{3}$/D',$number);

Alternatively, use \z which always matches the very end of the string, regardless of modifiers (thanks to Ωmega):

preg_match('/^[0-9]{3}\z/',$number);

You said "I may have something after it, too". If that means your string should start with exactly three digits, but there can be anything afterwards (as long as it's not another digit), you should use a negative lookahead:

preg_match('/^[0-9]{3}(?![0-9])/',$number);

Now it would match 123abc, too. The same can be applied to the beginning of the regex (if abc123def should give a match) using a negative lookbehind:

preg_match('/(?<![0-9])[0-9]{3}(?![0-9])/',$number);

Further reading about lookaround assertions.