TalkPHP
 
 
Account Login
Latest Articles
» How to keep your forms from double posting data
» cURL Basics
» Securing your PHP applications Part 1
» The way the function rolls
» Database Abstraction with Zend_Db - Part 2
Advertisement
Associates
Associates
techtuts Darkmindz
CSS Tutorials Tutorialsphere.com - Free Online Tutorials
Boston PHP SurfnLearn
Reply
 
LinkBack (1) Thread Tools Display Modes
Old 12-09-2007, 10:19 AM   #21 (permalink)
The Contributor
RegEx Guru 
 
Geert's Avatar
 
Join Date: Dec 2007
Location: Belgium
Posts: 58
Thanks: 5
Geert is on a distinguished road
Default

Great topic. I love talking about all the tiny details of regular expressions. They do matter!

Nobody has made a comment on the very first regex though.

Quote:
Originally Posted by Matt83 View Post
Validating a Username:
PHP Code:
$string "userNaME4234432_";
if (
preg_match('/^[a-z\d_]{4,28}$/i'$string)) { 
echo 
"example 1 successful.";

I'm telling you this username regex is flawed. Have a good look at it. Think. Test it. Then read on for the explanation.


The Problem

Okay, the often made mistake is to think that $ matches at the end of a string. The truth is that by default $ matches immediately before the final character if it is a newline.

This means that usernames containing a newline character at the end would pass. You wouldn't want that, right?


The Solution

Simply alter the meaning of $ by applying the D modifier to your regex. This will make it match only at the real end of the string. Alternatively, you could use the \z metacharacter.

The example below should make it all crystal clear, I hope.

PHP Code:
$username "mr_newline\n";

preg_match('/^[a-z\d_]{4,28}$/i',  $username); // TRUE
preg_match('/^[a-z\d_]{4,28}$/iD'$username); // FALSE
preg_match('/^[a-z\d_]{4,28}\z/i'$username); // FALSE 

Further Reading
Geert is offline  
Reply With Quote
The Following 2 Users Say Thank You to Geert For This Useful Post:
Jay (12-09-2007), Matt83 (12-09-2007)
Old 12-09-2007, 12:47 PM   #22 (permalink)
Jay
The Contributor
Good Samaritan 
 
Join Date: Dec 2007
Posts: 53
Thanks: 5
Jay is on a distinguished road
Default

Interesting, thanks for the link to that blog post!
Jay is offline  
Reply With Quote
Old 12-09-2007, 02:17 PM   #23 (permalink)
TalkPHP Loves You
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Nottingham
Posts: 1,448
Thanks: 72
Wildhoney is on a distinguished road
Default

I was under the impression that the problem you mentioned above, Geert, was only applicable when regex was in multi-line - if you were to switch it over to single-line mode then the $ would match the end of the string and not before the new-line?
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is online now  
Reply With Quote
Old 12-09-2007, 02:42 PM   #24 (permalink)
The Contributor
RegEx Guru 
 
Geert's Avatar
 
Join Date: Dec 2007
Location: Belgium
Posts: 58
Thanks: 5
Geert is on a distinguished road
Default

Quote:
Originally Posted by Wildhoney View Post
I was under the impression that the problem you mentioned above, Geert, was only applicable when regex was in multi-line - if you were to switch it over to single-line mode then the $ would match the end of the string and not before the new-line?
If you switch to multiline mode, by applying the m modifier, the D modifier is completely ignored. So $ will keep on matching before newlines as it does by default. However, you still could use \z.

PHP Code:
$str "line1\nline2\n";

echo 
preg_match('/^line2$/m',  $str); // TRUE
echo preg_match('/^line2$/mD'$str); // TRUE (D is ignored)
echo preg_match('/^line2\z/m'$str); // FALSE 
Geert is offline  
Reply With Quote
Old 12-16-2007, 01:52 AM   #25 (permalink)
The Contributor
 
webosb's Avatar
 
Join Date: Nov 2007
Posts: 30
Thanks: 20
webosb is on a distinguished road
Default

Quote:
Originally Posted by Matt83 View Post
Postal Codes:

PHP Code:
$string "55324-4324";
if (
preg_match('/^[0-9]{5,5}([- ]?[0-9]{4,4})?$/'$string)) { 
echo 
"example 4 successful.";

Looks like validating postal codes only work for US Postal Codes. Austalaia has 4 digit zip codes and UK has letters ...Is there a way to make the Postal Code validation work internationally?
__________________
one outstanding employee does more and costs less than two adequate performers.
webosb is offline  
Reply With Quote
Old 12-16-2007, 07:36 AM   #26 (permalink)
The Contributor
RegEx Guru 
 
Geert's Avatar
 
Join Date: Dec 2007
Location: Belgium
Posts: 58
Thanks: 5
Geert is on a distinguished road
Default

Quote:
Originally Posted by webosb View Post
Is there a way to make the Postal Code validation work internationally?
No, not in one regex at least. What if you enter only digits (valid Australian zip) but you live in the UK? The regex can't know.

So, first make sure you know what country the user is from. Then load the corresponding regex to validate zip.
Geert is offline  
Reply With Quote
Old 01-17-2008, 07:32 PM   #27 (permalink)
The Acquainted
 
obolus's Avatar
 
Join Date: Oct 2007
Location: florida
Posts: 110
Thanks: 36
obolus is on a distinguished road
Default

Here's a cheat sheet for Regular Expressions: Regular Expressions Cheat Sheet - Cheat Sheets - ILoveJackDaniels.com
obolus is offline  
Reply With Quote
The Following 2 Users Say Thank You to obolus For This Useful Post:
Alan @ CIT (01-17-2008), Wildhoney (01-17-2008)
Old 01-17-2008, 07:58 PM   #28 (permalink)
TalkPHP Loves You
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Nottingham
Posts: 1,448
Thanks: 72
Wildhoney is on a distinguished road
Default

Fantastic cheat sheet. Thanks a lot!
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is online now  
Reply With Quote
Old 01-17-2008, 08:13 PM   #29 (permalink)
Alan @ CIT
Member of the Month
The Frequenter
Member of the Month Top Contributor 
 
Alan @ CIT's Avatar
 
Join Date: Apr 2005
Location: South UK
Posts: 482
Thanks: 51
Alan @ CIT is on a distinguished road
Default

Regular expressions still make about as much sense to me as Japanese but thanks for the cheat sheets - bookmarked for future use

Alan
Send a message via MSN to Alan @ CIT
Alan @ CIT is offline  
Reply With Quote
Old 01-17-2008, 08:51 PM   #30 (permalink)
TalkPHP Loves You
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Nottingham
Posts: 1,448
Thanks: 72
Wildhoney is on a distinguished road
Default

Code:
Regex is really (easy|difficult)
!
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is online now  
Reply With Quote
Old 01-17-2008, 08:53 PM   #31 (permalink)
The Addict
 
Join Date: Nov 2007
Posts: 265
Thanks: 2
TlcAndres is on a distinguished road
Default

Quote:
Originally Posted by Alan @ CIT View Post
Regular expressions still make about as much sense to me as Japanese but thanks for the cheat sheets - bookmarked for future use

Alan
Sometimes it's the same for me and I understand Japanese,So the headache I aquire are easy to imagine lol.
TlcAndres is offline  
Reply With Quote
Old 02-10-2008, 01:21 PM   #32 (permalink)
The Addict
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 234
Thanks: 5
Kalle is on a distinguished road
Default

Great cheat sheet ;)
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 02-19-2008, 03:53 PM   #33 (permalink)
The Wanderer
 
Join Date: Feb 2008
Location: Blackpool, England
Posts: 7
Thanks: 1
Andrial12 is on a distinguished road
Default

If your based in the UK and stuck for Postcode and Telephone formatting ideas.

Try these

php Code:
// POSTCODES - will work for every UK postcode including the very strange GIRO Bank one.
$pattern = '/(^gir\s0aa$)|(^[a-pr-uwyz]((\d{1,2})|([a-hk-y]\d{1,2})|(\d[a-hjks-uw])|([a-hk-y]\d[abehmnprv-y]))\s\d[abd-hjlnp-uw-z]{2}$)/i';
if (!preg_match($pattern, $postcode)) {
    // Display Error
}


// Valids all uk numbers including +44's or anything like that
$telephone = str_replace(" ","",$telephone);
$telephone = str_replace("+","",$telephone);
$pattern = '/^01[1-9]{1}|02[03489]{1}|05[0-9]|07[056789]{1}|08[047]{1}|441[1-9]{1}|442[03489]{1}|445[0-9]|447[056789]{1}|448[047]{1}$/Ui';
if (!preg_match($pattern, $telephone)) {
    // Display Error
} else {
    if(substr($telephone, 0, 2) == "44") {
        $telephone = "0" . substr($telephone, 3, strlen($telephone));
    }
    if(strlen($telephone < 10)) {
        // Display Error
    }   
}

Last edited by Andrial12 : 02-19-2008 at 08:00 PM. Reason: Removed some code relating to a website I produced that isn't important to the workings of the code
Andrial12 is offline  
Reply With Quote
Old 02-19-2008, 06:11 PM   #34 (permalink)
The Frequenter
 
ReSpawN's Avatar
 
Join Date: Nov 2007
Location: Netherlands
Posts: 399
Thanks: 47
ReSpawN is on a distinguished road
Default

Andrial, next time usetags for your message. It looks fine non the less!
__________________
The Addict :: Addicted to (talk)PHP!
Send a message via MSN to ReSpawN
ReSpawN is offline  
Reply With Quote
Old 02-19-2008, 06:13 PM   #35 (permalink)
The Frequenter
 
ReSpawN's Avatar
 
Join Date: Nov 2007
Location: Netherlands
Posts: 399
Thanks: 47
ReSpawN is on a distinguished road
Default

Andrial, next time use php tags (between []) tags for your message. It looks fine non the less!
__________________
The Addict :: Addicted to (talk)PHP!
Send a message via MSN to ReSpawN
ReSpawN is offline  
Reply With Quote
The Following User Says Thank You to ReSpawN For This Useful Post:
Andrial12 (02-19-2008)
Old 03-19-2008, 03:31 AM   #36 (permalink)
The Gregarious
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Cana'derr
Posts: 653
Thanks: 24
delayedinsanity is on a distinguished road
Default What if?

Forgive me if this is a stupid question, but I've been a long time away from regular expressions. If you wanted to check a username and make sure it was all alphanumeric, but didn't start with a number, would the following be right?

/^[a-z]+[a-z\d_]{3,27}$/iD



Edit: er, maybe this would make more sense?
/^[a-z]{1}[a-z\d_]{3,27}$/iD
delayedinsanity is offline  
Reply With Quote
Old 03-19-2008, 09:39 PM   #37 (permalink)
The Addict
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 331
Thanks: 3
xenon is on a distinguished road
Default

Code:
/^[a-z][a-zA-Z0-9_]{3,27}$/
{1} may be omitted in this case since you only need one letter to validate the beginning of the string, so the repetition doesn't make any sense.
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
xenon is offline  
Reply With Quote
Old 03-19-2008, 10:48 PM   #38 (permalink)
The Gregarious
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Cana'derr
Posts: 653
Thanks: 24
delayedinsanity is on a distinguished road
Default

Thank you. Just so everybody knows, I did test that before asking, I was just curious if it was the most efficient method. In that line of thinking, I also noticed you changed \d to 0-9 .. isn't it the same thing or is one way better than the other?
-m
delayedinsanity is offline  
Reply With Quote
Old 03-19-2008, 11:13 PM   #39 (permalink)
The Addict
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 331
Thanks: 3
xenon is on a distinguished road
Default

I just used 0-9 instead of \d purely out of habit (and for consistency, I might add). \d and [0-9] are the same thing. Doesn't really matter which one of them you're using. I think the regex engine would have to first find the character group related to \d before matching, but that's fantasy already.
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
xenon is offline  
Reply With Quote
Old 04-24-2008, 09:40 PM   #40 (