kartul Posted April 8, 2011 Share Posted April 8, 2011 Hello all! I'm trying to create registration and login system for my page and I want usernames contain only a-zA-Z0-9._- characters. So I use preg_match in if statement to check that (is this right way?) but it gives me an error. I googled but no answer for me. Here is the error: Warning: preg_match() [function.preg-match]: Compilation failed: range out of order in character class at offset 13 in C:\wamp\www\i-have-a-secret\index.php on line 18 And the if statement that produces the error message: $username = (isset($_POST['username']) && strlen($_POST['username']) <= 25 && strlen($_POST['username']) >= 2 && preg_match('([a-zA-Z0-9._- ]+)', $_POST['username'])) ? $filter->process($_POST['username']) // just returns mysql safe string : false; Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/ Share on other sites More sharing options...
Maq Posted April 8, 2011 Share Posted April 8, 2011 I'm pretty sure you're missing delimiters around your expression. Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1198915 Share on other sites More sharing options...
Maq Posted April 8, 2011 Share Posted April 8, 2011 Sorry, I'm not sure why, probably because '-' implies range, but you need to put that character at the end of your pattern: '([a-zA-Z0-9._ -]+)' Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1198917 Share on other sites More sharing options...
kartul Posted April 8, 2011 Author Share Posted April 8, 2011 Now, the error is gone, thank you! *sits and thinks for a minute* but it doesn't really solve what I was hoping for... I have new question now, how do I get that if username contains characters other than what's in this regexpression, the if statement fails? Is there are some kind of function that I doesn't know of? Or what is the right way to do it? Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1198924 Share on other sites More sharing options...
Maq Posted April 8, 2011 Share Posted April 8, 2011 Try adding '^'. Which basically means, not: '([^a-zA-Z0-9._ -]+)' Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1198925 Share on other sites More sharing options...
kartul Posted April 8, 2011 Author Share Posted April 8, 2011 Try adding '^'. Which basically means, not: '([^a-zA-Z0-9._ -]+)' Wow that did the trick! To my understanding, the ^ means beginning of a string. But I guess in some context it's not, lol. Thanks a lot man! Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1198927 Share on other sites More sharing options...
Maq Posted April 8, 2011 Share Posted April 8, 2011 Try adding '^'. Which basically means, not: '([^a-zA-Z0-9._ -]+)' Wow that did the trick! To my understanding, the ^ means beginning of a string. But I guess in some context it's not, lol. Thanks a lot man! Yes it does, when it's not in the brackets. I'm not sure of the technical terms, but here is a good tutorial: http://www.phpfreaks.com/tutorial/regular-expressions-part1---basic-syntax Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1198932 Share on other sites More sharing options...
kartul Posted April 8, 2011 Author Share Posted April 8, 2011 Try adding '^'. Which basically means, not: '([^a-zA-Z0-9._ -]+)' Wow that did the trick! To my understanding, the ^ means beginning of a string. But I guess in some context it's not, lol. Thanks a lot man! Yes it does, when it's not in the brackets. I'm not sure of the technical terms, but here is a good tutorial: http://www.phpfreaks.com/tutorial/regular-expressions-part1---basic-syntax How could I have missed it. Thank you! Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1198940 Share on other sites More sharing options...
salathe Posted April 9, 2011 Share Posted April 9, 2011 Just in case things aren't clear, lets go over the fixes offered. Fixing the "range out of order in character class" error caused by [a-zA-Z0-9._- ] (since that is the only character class in the regex!). Ranges are things like a-z, which covers the range of characters starting at a and ending at z (so, the alphabet), and 0-9. Breaking apart your character class, there are in fact four ranges specified: 1. a-z, 2. A-Z, 3. 0-9 and 4. _-<space> where <space> is a literal space character. It is this final, accidental, range which causes the problem. It is worth going on a little bit of a tangent here and mentioning that the start/end characters for ranges must be in order, meaning that z-a is not valid. Take a look at a table of ASCII characters and note that the ASCII number of the range characters must be from low to high. Taking the values for underscore and space, 95 and 32 respectively, we can see that the order is incorrect just like z-a. If you were to have written the character class as [a-zA-Z0-9. -_], there would have been no error message because it is perfectly okay to have a range of "space to underscore"... however (again, take a look at the ASCII table) that would allow matching of any character between space and underscore, things like !, %, =, and @! Negating the character class First, that is the technical term for [^…]. That changed the regex from asking, "can I match a sequence of one or more characters from the character class, anywhere within the subject string?" to "can I match a sequence of one or more characters that are not from the character class, anywhere in the subject string?" The idea works, but it is also possible to make life simpler. Currently you have [^a-zA-Z0-9._ -]+, however all that you really care about is finding any occurrence of an invalid character. If we can match one bad character, and exit from trying to match anything more at that point, then that makes life easier on the regex engine doing all of the hard work. So, instead of asking for "one or more", we can just ask for "one"; this is done simply by removing the + repetition quantifier (i.e. we don't care about matching the character class more than once). This is a very minor point, but always worth keeping in mind as no-one likes doing more work than is really necessary, computers included! P.S. Good luck with the rest of the system. Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1199048 Share on other sites More sharing options...
Maq Posted April 11, 2011 Share Posted April 11, 2011 ^ Showoff... Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1200091 Share on other sites More sharing options...
salathe Posted April 12, 2011 Share Posted April 12, 2011 ^ Showoff... Sometimes I just have to let the little helpful badger type something, else he gets upset! Quote Link to comment https://forums.phpfreaks.com/topic/233120-preg_match-error/#findComment-1200719 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.