TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack (1) Thread Tools Search this Thread Display Modes
Old 12-09-2007, 11:19 AM   #21 (permalink)
The Contributor
RegEx Guru 
 
Join Date: Dec 2007
Location: Belgium
Posts: 60
Thanks: 6
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
__________________
Kohana - PHP5 framework
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, 01:47 PM   #22 (permalink)
Jay
The Contributor
Good Samaritan 
 
Join Date: Dec 2007
Posts: 60
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, 03:17 PM   #23 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,258
Thanks: 90
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 offline  
Reply With Quote
Old 12-09-2007, 03:42 PM   #24 (permalink)
The Contributor
RegEx Guru 
 
Join Date: Dec 2007
Location: Belgium
Posts: 60
Thanks: 6
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 
__________________
Kohana - PHP5 framework
Geert is offline  
Reply With Quote
Old 12-16-2007, 02:52 AM   #25 (permalink)
The Contributor
 
webosb's Avatar
 
Join Date: Nov 2007
Posts: 41
Thanks: 24
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?
__________________
"Things you can get access to, you should never memorize." -Albert Einstein
"They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin
webosb is offline  
Reply With Quote
Old 12-16-2007, 08:36 AM   #26 (permalink)
The Contributor
RegEx Guru 
 
Join Date: Dec 2007
Location: Belgium
Posts: 60
Thanks: 6
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.
__________________
Kohana - PHP5 framework
Geert is offline  
Reply With Quote
Old 01-17-2008, 08: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, 08:58 PM   #28 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,258
Thanks: 90
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 offline  
Reply With Quote
Old 01-17-2008, 09: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: 483
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, 09:51 PM   #30 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,258
Thanks: 90
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 offline  
Reply With Quote
Old 01-17-2008, 09:53 PM   #31 (permalink)
The Addict
 
Join Date: Nov 2007
Posts: 264
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, 02:21 PM   #32 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
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, 04:53 PM   #33 (permalink)
The Wanderer
 
Join Date: Feb 2008
Location: Blackpool, England
Posts: 16
Thanks: 2
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 09: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, 07:13 PM   #34 (permalink)
The Frequenter
 
ReSpawN's Avatar
 
Join Date: Nov 2007
Location: Netherlands
Posts: 460
Thanks: 49
ReSpawN is on a distinguished road
Default

Andrial, next time use php tags (between []) tags for your message. It looks fine non the less!
__________________
"Life is a bitch, take that bitch on a ride"
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, 04:31 AM   #35 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
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, 10:39 PM   #36 (permalink)
The Frequenter
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
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, 11:48 PM   #37 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
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-20-2008, 12:13 AM   #38 (permalink)
The Frequenter
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
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, 10:40 PM   #39 (permalink)
The Frequenter
Zend Certified 
 
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
Kalle is on a distinguished road
Default

Code:
#^\d{0,8}$#
Will match danish phone numbers =)
__________________
Send a message via MSN to Kalle Send a message via Skype™ to Kalle
Kalle is offline  
Reply With Quote
Old 04-25-2008, 08:03 AM   #40 (permalink)
The Visitor
 
Join Date: Apr 2008
Posts: 1
Thanks: 0
kikloo is on a distinguished road
Default

Hi,

PHP Code:
// Check Valid E-Mail
if (!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"$_POST["email"])) { echo "Email Address is not valid."; }

// Check valid URL
if (!preg_match('/^(http|https):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\//i'$_POST["url"])) { echo "Website URL is not valid."; } 
Thanks.
kikloo is offline  
Reply With Quote
Reply


LinkBacks (?)
LinkBack to this Thread: http://www.talkphp.com/advanced-php-programming/1612-8-practical-php-regular-expressions.html
Posted By For Type Date
Digg - Regular expressions for the PHP NooB! This thread Refback 12-25-2007 06:06 PM

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 07:32 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design