I would like to prevent new users from including apostophes, quotations and other special characters in their userids and passwords as I've found these can create unexpected problems down the road. Rather than anticipate every one of these problems, I'd rather just prohibit users from including those characters when signing up in the first place.
There are a lot of questions and stuff on the web in how to escape them to put them in the database but that is not the issue. I just want to throw an error msg that says enter something different.
I have tried:
$username = $_POST['username'];
if (preg_match ("/[&<>%\*\,\.\'\"]/i", $uid)) {
$strError="Your userid may not contain a special character. Please try again.";
}
but this is throwing an error No ending delimiter ''' found.
Would appreciate any suggestions.
Thanks.
I think you are going about this the wrong way. Instead of blacklisting special chars try whitelisting letters and digits e.g.
$username = $_POST['username'];
if (!preg_match('/^[\w\d]$/', $uid)) {
$strError="Your userid may not contain a special character. Please try again.";
}
to include asterisk and semicolon:
$username = $_POST['username'];
if (!preg_match('/^[\w\d\*;]$/', $uid)) {
$strError="Your userid may not contain a special character. Please try again.";
}
simplify it ...
<?php
$username = $_POST["username"];
if ( preg_match( "/^[A-Za-z0-9_]{3,20}$/", $username ) ) {
// username is valid
}
else {
// it contains special chars
}
?>
explaining regex...
"/^[
A-Z # any uppercase letters
a-z # any lowercase letters
0-9 # any digits
_ # underscore
]{3,20} # minimum 3 and maximum 20 characters
$/x"
The syntax highlighter shows you your obvious error: you have an extra ' on this line:
$username = $_POSt['username']';
should be
$username = $_POST['username'];
if (preg_match('/[^a-zA-Z]+/', $your_string, $matches))
{
echo 'Your userid may not contain a special character. Please try again.';
}
else
{
// No special characters found
}
may I suggest you not do that with preg_match ?
php has better functions for "sanitizing" strings - e.g. filter_var - check out FILTER_SANITIZE_STRING
I would suggest this snippet
$usernameRaw = trim($_POST['username']);
$username = filter_var( $usernameRaw , FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
Related
I am looking for a Regex to use in PHP in order to match one character; the # symbol.
For example, if I typed: P#ssword into an input, the Regex will match. If I typed P##ssword into an input, the regex will not match.
Here is my PHP Code that I am using:
<?php
session_start();
if($_SERVER['REQUEST_METHOD'] == "POST") {
$conn=mssql_connect('d','dd','d');
mssql_select_db('d',$conn);
if(! $conn )
{
die('Could not connect: ' . mssql_get_last_message());
}
$username = ($_POST['username']);
$password = ($_POST['password']);
if (preg_match("[\W]",$_POST["password"]))
{
if (!preg_match("^[^#]*#[^#]*$",$_POST["password"]))
{
header("location:logingbm.php");
} else {
}
}
if(!filter_var($_POST['username'], FILTER_VALIDATE_EMAIL))
{
if ($_POST["username"])
{
if ($_POST["password"])
{
$result = mssql_query("SELECT * FROM staffportal WHERE email='".$username."' AND
password='".$password."'");
if(mssql_num_rows($result) > 0) {
$_SESSION['staff_logged_in'] = 1;
$_SESSION['username'] = $username;
}}}} else {
if ($_POST["password"])
{
$result = mssql_query("SELECT * FROM staffportal WHERE email='".$username."' AND
password='".$password."'");
if(mssql_num_rows($result) > 0) {
$_SESSION['staff_logged_in'] = 1;
$_SESSION['username'] = $username;
}}}}
if(!isset($_SESSION['staff_logged_in'])) {
header("location:logingbm.php");
echo "<script>alert('Incorrect log-in information!');</script>";
} else {
header("location:staffportal.php");
}
?>
Other lightweight approaches...
Without regex
Just use substr_count (see demo)
<?php
$str1 = "pa#s#s";
$str2 = "pa#ss";
echo (substr_count($str1,"#")==1)?"beauty\n":"abject\n"; // abject
echo (substr_count($str2,"#")==1)?"beauty\n":"abject\n"; // beauty
With regex
EDIT: just saw that Sam wrote something equivalent.
If you want to use regex, you could use this fairly simple regex:
#
How? This code (see demo)
<?php
$str1 = "pa#s#s";
$str2 = "pa#ss";
$regex = "~#~";
echo (preg_match_all($regex,$str1,$m)==1)?"beauty\n":"abject\n"; // abject
echo (preg_match_all($regex,$str2,$m)==1)?"beauty\n":"abject\n"; // beauty
The easiest way would be to use the return value of preg_match_all().
Returns the number of full pattern matches (which might be zero), or FALSE if an error occurred.
Example:
$count = preg_match_all('/#/', $password, $matches);
Non regex solution (based off of #cdhowie's comment):
$string = 'P#ssword';
$length = strlen($string);
$count = 0;
for($i = 0; $i < $length; $i++) {
if($string[$i] === '#') {
$count++;
}
}
This works because you can access characters of Strings as you would with normal arrays ($var = 'foo'; $var[0] = 'f';).
As I said in my comment, your pattern needs delimiters /, #, ~ or whatever you want (see the PHP doc for that and test yourself).
To be quickly sure that a string contains only one #, you can do that:
if (preg_match('~\A[^#]*#[^#]*\z~', $yourstr))
echo 'There is one #';
else
echo 'There is more than one # or zero #';
This regexp will do what you want:
^[^#]*#[^#]*$
This matches any line that contains one and only one #.
Explanation
^ matches the beginning of the line
[^#]* matches everything before the #
# matches the # character
[^#]* matches everything after the #
$ matches the end of the line
Use
preg_match("#^[^#]*#[^#]*$#", $passwd); //Matches $passwd if it contains only one character
Here's what your regex code means:
If there is at least one non-word character in the string ([\W]), there must be exactly one at-sign (#). There may be any number of any other characters before and after the at-sign: letters, digits, control characters, punctuation, anything. Anything but #.
What I'm wondering is, are you trying to say there can be not more than one at-sign (i.e. zero or one?) That's pretty simple, conceptually; just get rid of the first regex check ("[\W]") and change the second regex to this:
"^[^#]*(?:#[^#]*)?$"
In other words:
Start by consuming not at-signs you see. If you see a #, go ahead and consume it, then resume matching whatever not at-signs remain. If that doesn't leave you at the end of the string, it can only mean there were more than one #. Abandon the attempt immediately and report a failed match.
Of course, this still leaves you with the problem of which other characters you want to allow. I'm pretty sure [^#]* is not what you want.
Also, "[\W]" may be working as you intended, but it's only by accident. You could have written it "/\W/" or "~\W~" "(\W)" and it would work just the same. You may have meant those square brackets to form a character class, but they're not even part of the regex; they're the regex delimiters.
So why did it work, you ask? \W is a predefined character class, equivalent to [^\w]. You can use it inside a regular character class, but it works fine on its own.
I need help with preg match/replace forma i really cant understand how its working and what each element doing.
So far I have this:
$username = preg_replace('/\s+/', '_', $_POST['uname']);
if(preg_match('/^[a-zA-Z0-9]{5,12}+$/u', $username))
{
$username = trim(strip_tags(ucfirst($purifier->purify(#$_POST["uname"]))));
}
else
{
$message['uname']='wrong username input';
}
And for utf8(hebrew language) i got this:
if(preg_match("/^[\p{Hebrew} a-zA-Z0-9]{2,10}+$/u", $_POST['fname']))
{
//
}
which is working perfect, but I don't want to allow Hebrew on username just English.
I tried to play with that in multiple combinations, I tried to change but no success, and I did research on StackOverflow and Google but can't make it like I want I don't understand.
I used a RegEx site to and tried to build but with no success.
So until now I got this :
User can put 5-12 letters/numbers no special characters.
What i want is :
Can enter between 5-12 letters/numbers no special charcaters - i
already have it.
Allow whitespaces
preg_match if no mixed language's like E.G: $username = שדגדשsdsd; <- not allowed mixed languages.
And preg_replace to:
Replace white spaces to nothing (remove white spaces) i have this but i dont know if it correct:
$username = preg_replace('/\s+/', '', $_POST['uname']);
Also, I am using UTF-8 language .
EDIT:
With help of hwnd , i make it to work like i want the latest code:
if(preg_match('/^[\p{Hebrew}]{2,10}|[a-zA-Z]{2,10}$/u', $_POST['fname']) && preg_match('/^[a-zA-Z]{2,10}|[\p{Hebrew}]{2,10}$/u', $_POST['fname']))
{
$message = 'valid';
}else{
$message = 'Invalid';
}
Solved,Thanks.
I'm sure if your allowing whitespace in the username, you can suffice with just a space character but to be safe use \s which matches whitespace (\n, \r, \t, \f, and " "), for that you can just add that inside of your character class []
if (preg_match('/^[a-zA-Z0-9\s]{5,12}+$/u', $username)) { ...
And you can leave your preg_replace() function as is...
Update: To match different characters, but not mixed you could try the following:
$user = 'hwדגדשרביd'; // "invalid"
$user = 'fooo'; // "valid"
$user = 'שדגדשרביב'; // "valid"
if (preg_match('/^[\p{Hebrew}]{2,10}|[a-zA-Z]{2,10}$/u', $user)) {
echo "valid";
} else {
echo "invalid";
}
Your preg_replace for removing whitespace from the username is fine.
To allow only English letters, digits and whitespace in the username, use this:
if (preg_match('/^[a-zA-Z0-9\s]{5,12}+$/u', $username)) {
# $username is OK
}
else {
# $username is not OK
}
I'm pretty stupid to regexp but I have to use this... I have to validate a username field that must match to this scheme: "Firstname_Lastname"
This means that the valid username is only alphabet separated by an underscore. The first name and the last name must start with uppercase but the rest of them must be lowercase.
I have tried this but it's not working:
<?php
$username = "Dani_Sebi";
$regex = '/^[A-Z][a-z]+_^[A-Z][a-z]+/';
if (preg_match($regex, $username)) {
echo $username . " is a valid username. We can accept it.";
} else {
echo $username . " is an invalid username. Please try again.";
}
?>
^ is misplaced inside the reex. Try this:
$regex = '/^([A-Z][a-z]+)_([A-Z][a-z]+)/';
I bet this could be improved, but it works:
^[A-Z][a-z]+_[A-Z][a-z]+$
^[:upper:][:lower:]*_[:upper:][:lower:]*$
There are single letter names as well, so this one is better.
When people sign up to my site I validate their names with this code:
if (preg_match("[\W]", $name))
{
$mess = $mess . "Your name must contain letters only.<br>";
$status = "NOTOK";
}
This is because your actual name cannot contain symbols unless your parents were drunk when they named you.
However, this regex doesn't detect spaces. How can I fix it?
You can use the following regular expression:
^[\w ]+$
This matches any combinations of word characters \w and spaces , but as the guys said be careful because some names might contain other symbols.
So you can use it like this:
if (preg_match("/^[\\w ]+$/", $name)) {
// valid name
}
else {
// invalid name
}
Try this:
<?php
$user_input = 'User_name';
if (!preg_match('/^[a-z0-9_\s]+$/i', $user_input)) {
// Matches English letters, numbers underscores(_) and spaces
$mess = $mess . "Your name must contain letters only.<br>";
$status = "NOTOK";
}
?>
You just missed regexp separators. I do this sometimes even after 10 years of programming.
if (preg_match("/[\W]/", $name)) ...
I am not very good in Regular Expression, and can't seem to understand them quite well.
I am looking for a regular expression which will match and allow following strings for a username, with these conditions:
username can: start with a number or with a alphabetic letter
username can contain special chars: dots, dashes, underscores
username must be in this range: from 3 chars up to 32 chars.
alphanumeric characters in the username can be both: lowercase and uppercase
cannot contain empty spaces
Almost similar to Twitter's and Facebook username patterns.
Please help me. Thank you.
FWI: I have tried this: /^(?=.{1,15}$)[a-zA-Z][a-zA-Z0-9]*(?: [a-zA-Z0-9]+)*$/ - and this does not satisfy my conditions.
Try this one
^[a-zA-Z0-9][a-zA-Z0-9\._-]{2,31}$
this results in the php code
if (preg_match('~^[a-zA-Z0-9][a-zA-Z0-9\._-]{2,31}$~', $username) {
//do something
}
Starts with digit or alphabetic
[a-zA-Z0-9]
can contain as above plus dots, dashes and underscores
[a-zA-Z0-9._-]
and all together
[a-zA-Z0-9][a-zA-Z0-9._-]{2, 31}
try this one this is working for me in every registration form
//username Validation
var usernameRegex = /^[a-zA-Z0-9\s\[\]\.\-#']*$/i;
var username=document.getElementById('username');
if(username.value==""){
document.getElementById('lblusername').innerHTML="Username Required!";
username.focus();
return false;
}
else if(usernameRegex.test(username.value)== false)
{
document.getElementById('lblusername').innerHTML="Allow Alphanumeric Only! (E.g Demo123)";
username.focus();
return false;
}
else
{
document.getElementById('lblusername').innerHTML="";
}
Try this:
^[0-9a-zA-Z][0-9a-zA-Z\-\._]{2,31}$