PHP Pattern Matching - Is there a better solution?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • gsv2com

    PHP Pattern Matching - Is there a better solution?

    One of my weaknesses has always been pattern matching. Something I
    definitely need to study up on and maybe you guys can give me a pointer
    here.

    I'm looking to remove all of this code and just use pattern matching to
    determine if the proper amount of numeric characters has been met. Here is
    the function I've already done. Any help you can give in a pattern matching
    solution would be much appreciated and very educational.


    //the $area option is for determining if the user need (or need not) type in
    their area code.

    function check_phone($ph one,$area='y'){
    if($area=='y'){
    $min=10;
    } else {
    $min=7;
    }

    //is there a more direct approach to just count the amount of numbers in
    the string by pattern matching?
    $phone=str_repl ace('-','',$phone);
    $phone=str_repl ace('(','',$pho ne);
    $phone=str_repl ace(')','',$pho ne);
    $phone=str_repl ace(' ','',$phone);

    if(!preg_match( '/[\d]{'.$min.',}/',$phone)){
    return(FALSE);
    } else {
    return(TRUE);
    }
    }


  • Michael Fesser

    #2
    Re: PHP Pattern Matching - Is there a better solution?

    .oO(gsv2com)
    [color=blue]
    > //is there a more direct approach to just count the amount of numbers in
    >the string by pattern matching?
    > $phone=str_repl ace('-','',$phone);
    > $phone=str_repl ace('(','',$pho ne);
    > $phone=str_repl ace(')','',$pho ne);
    > $phone=str_repl ace(' ','',$phone);
    >
    > if(!preg_match( '/[\d]{'.$min.',}/',$phone)){
    > return(FALSE);
    > } else {
    > return(TRUE);
    > }
    > }
    >[/color]

    I would simply remove all the special chars and then check the length of
    the remaining string, no need for pattern matching here:

    function check_phone($ph one, $area = TRUE) {
    $min = $area ? 10 : 7;
    return strlen(str_repl ace(array('-', '(', ')', ' '), '', $phone)) >= $min;
    }

    HTH
    Micha

    Comment

    • chernyshevsky@hotmail.com

      #3
      Re: PHP Pattern Matching - Is there a better solution?

      Regular expression is definitely something that's worth spending the
      time mastering. In this case it's not strictly necessary. But for more
      complex validation, it'll makes your life a whole lot easier.

      Here's the pattern, built in pieces for educational purpose:

      $pattern = '';

      // the beginning of the string
      $pattern .= '^';

      // 0 or more white spaces (just in case)
      $pattern .= '\s*';
      if($area) {
      // optional open paren
      $pattern .= '\(?';

      // capturing 3 digits
      $pattern .= '(\d{3})';

      // optional close paren
      $pattern .= '\)';

      // optional dash, or space
      $pattern .= '[\- ]?';
      }

      // capturing next 3 digits
      $pattern .= '(\d{3})';

      // optional dash or space
      $pattern .= '[\- ]?';

      // capturing 4 digits
      $pattern .= '(\d{4})';

      // 0 or more white spaces
      $pattern .= '\s*';

      // end of string
      $pattern .= '$';

      // altogether >> '^\s*\(?(\d{3}) \)?[\- ]?(\d{3})[\- ]?(\d{4})\s*$'
      if(preg_match("/$pattern/", $phone, $matches)) {
      ...
      }

      Comment

      • Justin Koivisto

        #4
        Re: PHP Pattern Matching - Is there a better solution?

        gsv2com wrote:
        [color=blue]
        > One of my weaknesses has always been pattern matching. Something I
        > definitely need to study up on and maybe you guys can give me a pointer
        > here.
        >
        > I'm looking to remove all of this code and just use pattern matching to
        > determine if the proper amount of numeric characters has been met. Here is
        > the function I've already done. Any help you can give in a pattern matching
        > solution would be much appreciated and very educational.[/color]

        function check_phone($ph one,$area='y'){
        if($area=='y'){
        $min=10;
        } else {
        $min=7;
        }
        // remove any non-digit from the string
        $phone=preg_rep lace('/[^0-9]/','',$phone);

        return (strlen($phone) ==$min)? TRUE : FALSE;
        }

        Just be careful what you pass for the $area value. If you call:

        check_phone($ph one,0);

        You *will* need the area code. (string to int conversion in if statement).

        --
        Justin Koivisto - justin@koivi.co m

        Comment

        • Justin Koivisto

          #5
          Re: PHP Pattern Matching - Is there a better solution?

          chernyshevsky@h otmail.com wrote:
          [color=blue]
          > Regular expression is definitely something that's worth spending the
          > time mastering. In this case it's not strictly necessary. But for more
          > complex validation, it'll makes your life a whole lot easier.
          >
          > Here's the pattern, built in pieces for educational purpose:
          >
          > $pattern = '';
          >
          > // the beginning of the string
          > $pattern .= '^';
          >
          > // 0 or more white spaces (just in case)
          > $pattern .= '\s*';
          > if($area) {
          > // optional open paren
          > $pattern .= '\(?';
          >
          > // capturing 3 digits
          > $pattern .= '(\d{3})';
          >
          > // optional close paren
          > $pattern .= '\)';[/color]

          That isn't optional... this is ;)
          $pattern .= '\)?';
          [color=blue]
          > // optional dash, or space
          > $pattern .= '[\- ]?';
          > }
          >
          > // capturing next 3 digits
          > $pattern .= '(\d{3})';
          >
          > // optional dash or space
          > $pattern .= '[\- ]?';
          >
          > // capturing 4 digits
          > $pattern .= '(\d{4})';
          >
          > // 0 or more white spaces
          > $pattern .= '\s*';
          >
          > // end of string
          > $pattern .= '$';
          >
          > // altogether >> '^\s*\(?(\d{3}) \)?[\- ]?(\d{3})[\- ]?(\d{4})\s*$'
          > if(preg_match("/$pattern/", $phone, $matches)) {
          > ...
          > }[/color]

          Hmm.. might want to make that a bit more generic. I've seen users
          delimit phone number parts with characters other than a - or space (like
          a dot, long hyphen, comma, etc.).

          Maybe better would be something like this:

          ^[^\d]*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})[^\d]*$

          Of course, you could just remove all the non-digits:
          $phone=preg_rep lace('/[^\d]/','',$phone);

          Then simply compare the length of the string.

          --
          Justin Koivisto - justin@koivi.co m

          Comment

          • gsv2com

            #6
            Re: PHP Pattern Matching - Is there a better solution?

            Thanks for your help guys. As the end result, I used a combination of a few
            of your tips to make the finalized function:

            function check_phone($ph one,$area=TRUE) {
            $min = $area ? 10 : 7;
            $phone=preg_rep lace('/[^0-9]/','',$phone);
            return (strlen($phone) ==$min)? TRUE : FALSE;
            }

            Very nice. Thanks again.


            Comment

            • Michael Fesser

              #7
              Re: PHP Pattern Matching - Is there a better solution?

              .oO(gsv2com)
              [color=blue]
              >function check_phone($ph one,$area=TRUE) {
              > $min = $area ? 10 : 7;
              > $phone=preg_rep lace('/[^0-9]/','',$phone);
              > return (strlen($phone) ==$min)? TRUE : FALSE;
              >}[/color]

              JFTR: It's not necessary to explicitly return TRUE or FALSE in this
              case. It's redundant because the result of the comparision will already
              be of type boolean:

              return strlen($phone) == $min;

              does the same without another unnecessary operation.

              In the preg_replace() pattern you could also use the character class \d
              (digits) instead of 0-9:

              '/[^\d]/'

              And another thing: Are you sure the numbers will always exactly be 7 or
              10 digits long? At least here in Germany the length of phone numbers may
              vary. That's why I used >= instead of == in my example and your first
              code also suggested that.

              Micha

              Comment

              • Justin Koivisto

                #8
                Re: PHP Pattern Matching - Is there a better solution?

                Michael Fesser wrote:
                [color=blue]
                > .oO(gsv2com)
                >
                >[color=green]
                >>function check_phone($ph one,$area=TRUE) {
                >> $min = $area ? 10 : 7;
                >> $phone=preg_rep lace('/[^0-9]/','',$phone);
                >> return (strlen($phone) ==$min)? TRUE : FALSE;
                >>}[/color]
                >
                > JFTR: It's not necessary to explicitly return TRUE or FALSE in this
                > case. It's redundant because the result of the comparision will already
                > be of type boolean:
                >
                > return strlen($phone) == $min;
                >
                > does the same without another unnecessary operation.[/color]

                I usually include the explicit returns just for readability sake. ;)

                --
                Justin Koivisto - justin@koivi.co m

                Comment

                • R. Rajesh Jeba Anbiah

                  #9
                  Re: PHP Pattern Matching - Is there a better solution?

                  gsv2com wrote:[color=blue]
                  > One of my weaknesses has always been pattern matching.[/color]

                  <snip>

                  Perhaps you should try <http://www.weitz.de/regex-coach/>

                  --
                  <?php echo 'Just another PHP saint'; ?>
                  Email: rrjanbiah-at-Y!com Blog: http://rajeshanbiah.blogspot.com/

                  Comment

                  Working...