 |
Account Login
|
 |
 |
Latest Articles
|
 |
 |
Advertisement
|
 |
 |
Associates
|
 |
 |
Associates
|
 |
|
 |
|
 |
|
 |
12-09-2007, 10:19 AM
|
#21 (permalink)
|
|
The Contributor
Join Date: Dec 2007
Location: Belgium
Posts: 58
Thanks: 5
|
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
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
|
|
|
|
|
The Following 2 Users Say Thank You to Geert For This Useful Post:
|
|
12-09-2007, 12:47 PM
|
#22 (permalink)
|
|
The Contributor
Join Date: Dec 2007
Posts: 53
Thanks: 5
|
Interesting, thanks for the link to that blog post!
|
|
|
|
12-09-2007, 02:17 PM
|
#23 (permalink)
|
|
TalkPHP Loves You
Join Date: Sep 2007
Location: Nottingham
Posts: 1,448
Thanks: 72
|
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.
|
|
|
12-09-2007, 02:42 PM
|
#24 (permalink)
|
|
The Contributor
Join Date: Dec 2007
Location: Belgium
Posts: 58
Thanks: 5
|
Quote:
Originally Posted by Wildhoney
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
|
|
|
|
12-16-2007, 01:52 AM
|
#25 (permalink)
|
|
The Contributor
Join Date: Nov 2007
Posts: 30
Thanks: 20
|
Quote:
Originally Posted by Matt83
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.
|
|
|
|
12-16-2007, 07:36 AM
|
#26 (permalink)
|
|
The Contributor
Join Date: Dec 2007
Location: Belgium
Posts: 58
Thanks: 5
|
Quote:
Originally Posted by webosb
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.
|
|
|
|
01-17-2008, 07:32 PM
|
#27 (permalink)
|
|
The Acquainted
Join Date: Oct 2007
Location: florida
Posts: 110
Thanks: 36
|
|
|
|
|
|
The Following 2 Users Say Thank You to obolus For This Useful Post:
|
|
01-17-2008, 07:58 PM
|
#28 (permalink)
|
|
TalkPHP Loves You
Join Date: Sep 2007
Location: Nottingham
Posts: 1,448
Thanks: 72
|
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.
|
|
|
01-17-2008, 08:13 PM
|
#29 (permalink)
|
|
The Frequenter
Join Date: Apr 2005
Location: South UK
Posts: 482
Thanks: 51
|
Regular expressions still make about as much sense to me as Japanese but thanks for the cheat sheets - bookmarked for future use
Alan
|
|
|
01-17-2008, 08:51 PM
|
#30 (permalink)
|
|
TalkPHP Loves You
Join Date: Sep 2007
Location: Nottingham
Posts: 1,448
Thanks: 72
|
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.
|
|
|
01-17-2008, 08:53 PM
|
#31 (permalink)
|
|
The Addict
Join Date: Nov 2007
Posts: 265
Thanks: 2
|
Quote:
Originally Posted by Alan @ CIT
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.
|
|
|
|
02-10-2008, 01:21 PM
|
#32 (permalink)
|
|
The Addict
Join Date: Sep 2007
Location: Denmark
Posts: 234
Thanks: 5
|
Great cheat sheet ;)
|
|
|
02-19-2008, 03:53 PM
|
#33 (permalink)
|
|
The Wanderer
Join Date: Feb 2008
Location: Blackpool, England
Posts: 7
Thanks: 1
|
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
|
|
|
|
02-19-2008, 06:11 PM
|
#34 (permalink)
|
|
The Frequenter
Join Date: Nov 2007
Location: Netherlands
Posts: 399
Thanks: 47
|
Andrial, next time usetags for your message. It looks fine non the less!
__________________
The Addict :: Addicted to (talk)PHP!
|
|
|
02-19-2008, 06:13 PM
|
#35 (permalink)
|
|
The Frequenter
Join Date: Nov 2007
Location: Netherlands
Posts: 399
Thanks: 47
|
Andrial, next time use php tags (between []) tags for your message. It looks fine non the less!
__________________
The Addict :: Addicted to (talk)PHP!
|
|
|
|
The Following User Says Thank You to ReSpawN For This Useful Post:
|
|
03-19-2008, 03:31 AM
|
#36 (permalink)
|
|
The Gregarious
Join Date: Mar 2008
Location: Cana'derr
Posts: 653
Thanks: 24
|
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
|
|
|
|
03-19-2008, 09:39 PM
|
#37 (permalink)
|
|
The Addict
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 331
Thanks: 3
|
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.
|
|
|
|
03-19-2008, 10:48 PM
|
#38 (permalink)
|
|
The Gregarious
Join Date: Mar 2008
Location: Cana'derr
Posts: 653
Thanks: 24
|
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
|
|
|
|
03-19-2008, 11:13 PM
|
#39 (permalink)
|
|
The Addict
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 331
Thanks: 3
|
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.
|
|
|
|
04-24-2008, 09:40 PM
|
#40 ( | |