Welcome to Dream.In.Code
Become a PHP Expert!

Join 136,926 PHP Programmers for FREE! Get instant access to thousands of PHP experts, tutorials, code snippets, and more! There are 1,803 people online right now. Registration is fast and FREE... Join Now!




Using eregi() to Search for 2 numbers

 
Reply to this topicStart new topic

Using eregi() to Search for 2 numbers

chrisman
25 Mar, 2008 - 05:28 PM
Post #1

New D.I.C Head
Group Icon

Joined: 22 Mar, 2008
Posts: 41



Thanked: 1 times
Dream Kudos: 100
My Contributions
I have a form with four inputs. Username, Password, Email Address, and Mailing Address. Using eregi(), I have been validating each input. I got Username to work, but I ran into problems with Password. The requirements I want are:
  • Can only contain letters and numbers.
  • Must contain at least 2 numbers.
  • Must begin with a letter.

Here is my code:
CODE

<?php
  $passval1 = eregi("[a-z0-9][0-9]{2,}", $pass); // Look for 2 numbers in $pass.*
  $passval1 = (int)$passval1; // Change boolean to integer
  $passval2 = eregi("^[^a-z]", $pass); // Look for something other than a letter at the beginning of $pass
  $passval2 = (int)$passval2;
  $passval3 = eregi("[^a-z0-9]", $pass); // Look for something other than a letter or a number.
  $passval3 = (int)$passval3;

  if ($passval1 == 1 && $passval2 == 0 && $passval3 == 0 && $passleng >= 3 && $passleng <= 24)
   {
    echo "Your password was accepted by the system.<br />";
   }
  else
   {
    if ($passval3 == 1) // $passval3 was true; There was a symbol other than a letter or number.
     {
      echo "Password invalid. Your password may only consist of letters and numbers.<br />";
     }
    if ($passval2 == 1) // $passval2 was true; There was something other than a letter as the first letter.
     {
      echo "Password invalid. Your password must begin with a letter.<br />";
     }
    if ($passval1 == 0) // $passval1 was false; It didn't find two numbers.*
     {
      echo "Password invalid. Your password must contain at least two numbers.<br />";
     }
   }

// * means what was INTENDED, not what HAPPENED
?>


Look familiar? I got the idea from Speafish's tutorial, and I expanded on it.

Now, as you can see, what is *ed is what I wanted to happen. What actually happened was it looked for two numbers directly next to each other. This means that "abc1d2" isn't valid, although I want to to be. ("abc12d" would be valid, however.)

Thanks.
User is offlineProfile CardPM
+Quote Post

spearfish
RE: Using Eregi() To Search For 2 Numbers
25 Mar, 2008 - 06:29 PM
Post #2

Monkey in Training
Group Icon

Joined: 10 Mar, 2008
Posts: 746



Thanked: 2 times
Dream Kudos: 225
My Contributions
Well, first off you haven't defined $passlen in that code - and undefined variables, rather than having the parser bitch at you like in JavaScript, are assumed to be null, or if it needs to be assigned an integer value, zero. So it's not passing the gauntlet because 0 < 3. That caused me some head scratching when I first looked at this.

With that bug aside, screaming, "It does damn you!" doesn't work (though I wish it did). To find the root of this issue, we must look at what the eregi function is doing when it's searching the character class. Searching, eregi("[a-z0-9][0-9]{2,}") is actually looking for an alphanumeric character immediately followed by at least two numbers. Meaning, if the numbers are split up, that alphanumeric character isn't immediately followed by two numbers.

That's a really good question, and in retrospect, something that should have been covered. Oh well, perhaps I'll drive more confused readers to posting in the forums wink2.gif

What you can do to represent any character is just a period. So if you were to search for eregi("[0-9].[0-9]{2,}" your abc1d2 passes. But now there has to be something between the two numbers, filling the spot occupied by the period. To fix that, use a quantifier saying that the wildcard may be filled as many times as it needs to be - or maybe not at all! Meaning, search for .{0,} (or .*, same thing).

So the finished code is:

CODE

<?php

$passval1 = eregi("[0-9].*[0-9]", $pass); // Look for 2 numbers in $pass.*
  $passval1 = (int)$passval1; // Change boolean to integer
  $passval2 = eregi("^[^a-z]", $pass); // Look for something other than a letter at the beginning of $pass
  $passval2 = (int)$passval2;
  $passval3 = eregi("[^a-z0-9]", $pass); // Look for something other than a letter or a number.
  $passval3 = (int)$passval3;
  $passleng = strlen($pass);

  if ($passval1 == 1 && $passval2 == 0 && $passval3 == 0 && $passleng >= 3 && $passleng <= 24)
   {
    echo "Your password was accepted by the system.<br />";
   }
  else
   {
    if ($passval3 == 1) // $passval3 was true; There was a symbol other than a letter or number.
     {
      echo "Password invalid. Your password may only consist of letters and numbers.<br />";
     }
    if ($passval2 == 1) // $passval2 was true; There was something other than a letter as the first letter.
     {
      echo "Password invalid. Your password must begin with a letter.<br />";
     }
    if ($passval1 == 0) // $passval1 was false; It didn't find two numbers.*
     {
      echo "Password invalid. Your password must contain at least two numbers.<br />";
     }
   }

?>

User is offlineProfile CardPM
+Quote Post

chrisman
RE: Using Eregi() To Search For 2 Numbers
25 Mar, 2008 - 06:49 PM
Post #3

New D.I.C Head
Group Icon

Joined: 22 Mar, 2008
Posts: 41



Thanked: 1 times
Dream Kudos: 100
My Contributions
QUOTE(spearfish @ 25 Mar, 2008 - 07:29 PM) *

Well, first off you haven't defined $passlen in that code - and undefined variables, rather than having the parser bitch at you like in JavaScript, are assumed to be null, or if it needs to be assigned an integer value, zero. So it's not passing the gauntlet because 0 < 3. That caused me some head scratching when I first looked at this.


Sorry, $passleng = strlen($pass); wasn't included. I didn't copy the whole code because it included info on other input validators. More confusion = less responses. wink2.gif Also, $pass = $_POST['pass']; was another line I left out, referring to my form input. (in case that also confused you. I am a forgetful programmer!)

I am going to add two if() statements to keep the password between 3 and 24 characters.

QUOTE(spearfish @ 25 Mar, 2008 - 07:29 PM) *

What you can do to represent any character is just a period. So if you were to search for eregi("[0-9].[0-9]{2,}" your abc1d2 passes. But now there has to be something between the two numbers, filling the spot occupied by the period. To fix that, use a quantifier saying that the wildcard may be filled as many times as it needs to be - or maybe not at all! Meaning, search for .{0,} (or .*, same thing).


Thanks! I knew there had to be a character I was missing. I tried a bunch of other combos (and just eregi("[0-9]{2,}"); caused an error. It, of course, works now. biggrin.gif

This post has been edited by chrisman: 25 Mar, 2008 - 06:51 PM
User is offlineProfile CardPM
+Quote Post

spearfish
RE: Using Eregi() To Search For 2 Numbers
25 Mar, 2008 - 06:53 PM
Post #4

Monkey in Training
Group Icon

Joined: 10 Mar, 2008
Posts: 746



Thanked: 2 times
Dream Kudos: 225
My Contributions
Glad I could help!

My mistake, I should have included that in the tutorial - that's been appended.
User is offlineProfile CardPM
+Quote Post

chrisman
RE: Using Eregi() To Search For 2 Numbers
25 Mar, 2008 - 11:24 PM
Post #5

New D.I.C Head
Group Icon

Joined: 22 Mar, 2008
Posts: 41



Thanked: 1 times
Dream Kudos: 100
My Contributions
Mwhaa! If you want to see what page this snippet went into, its
http://qae.x10hosting.com/scripts/php/thegauntlet.php
This bit became part of a 250-line page. Woo!
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/3/08 10:23PM

Live PHP Help!

PHP Tutorials

Reference Sheets

PHP Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month