Muhammad Sohail
Muhammad Sohail

Reputation: 598

php regular expression minimum and maximum length doesn't work as expected

I want to create a regular expression in PHP, which will allow to user to enter a phone number in either of the formats below.

345-234 898

345 234-898

235-123-456

548 812 346

The minimum length of number should be 7 and maximum length should be 12.

The problem is that, the regular expression doesn't care about the minimum and maximum length. I don't know what is the problem in it. Please help me to solve it. Here is the regular expression.

if (preg_match("/^([0-9]+((\s?|-?)[0-9]+)*){7,12}$/", $string)) {
echo "ok";
} else {
echo "not ok";
}

Thanks for reading my question. I will wait for responses.

Upvotes: 2

Views: 7422

Answers (6)

fahdshaykh
fahdshaykh

Reputation: 682

may it help you out.

Validator::extend('price', function ($attribute, $value, $args) {
return preg_match('/^\d{0,8}(\.\d{1,2})?$/', $value);
});

Upvotes: 0

Socheatha Tey
Socheatha Tey

Reputation: 43

You should use the start (^) and the end ($) sign on your pattern

$subject = "123456789";
    $pattern = '/^[0-9]{7,9}$/i';
    if(preg_match($pattern, $subject)){
        echo 'matched';
    }else{
        echo 'not matched';
    }

Upvotes: 3

Ulugbek Umirov
Ulugbek Umirov

Reputation: 12797

You can use preg_replace to strip out non-digit symbols and check length of resulting string.

$onlyDigits = preg_replace('/\\D/', '', $string);
$length = strlen($onlyDigits);
if ($length < 7 OR $length > 12)
  echo "not ok";
else
  echo "ok";

Upvotes: 2

newfurniturey
newfurniturey

Reputation: 38416

Breaking down your original regex, it can read like the following:

^                   # start of input
(
    [0-9]+          # any number, 1 or more times
    (
        (\s?|-?)    # a space, or a dash.. maybe
        [0-9]+      # any number, 1 or more times
    )*              # repeat group 0 or more times
)
{7,12}              # repeat full group 7 to 12 times
$                   # end of input

So, basically, you're allowing "any number, 1 or more times" followed by a group of "any number 1 or more times, 0 or more times" repeat "7 to 12 times" - which kind of kills your length check.

You could take a more restricted approach and write out each individual number block:

(
    \d{3}         # any 3 numbers
    (?:[ ]+|-)?   # any (optional) spaces or a hyphen
    \d{3}         # any 3 numbers
    (?:[ ]+|-)?   # any (optional) spaces or a hyphen
    \d{3}         # any 3 numbers
)

Simplified:

if (preg_match('/^(\d{3}(?:[ ]+|-)?\d{3}(?:[ ]+|-)?\d{3})$/', $string)) {

If you want to restrict the separators to be only a single space or a hyphen, you can update the regex to use [ -] instead of (?:[ ]+|-); if you want this to be "optional" (i.e. there can be no separator between number groups), add in a ? to the end of each.

if (preg_match('/^(\d{3}[ -]\d{3}[ -]\d{3})$/', $string)) {

Upvotes: 0

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

You can check the length with a lookahead assertion (?=...) at the begining of the pattern:

/^(?=.{7,12}$)[0-9]+(?:[\s-]?[0-9]+)*$/

Upvotes: 2

Sabuj Hassan
Sabuj Hassan

Reputation: 39355

Simply do this:

if (preg_match("/^\d{3}[ -]\d{3}[ -]\d{3}$/", $string)) {

Here \d means any digits from 0-9. Also [ -] means either a space or a hyphen

Upvotes: 2

Related Questions