Regular expression for validating a username? - php

I'm still kinda new to using Regular Expressions, so here's my plight. I have some rules for acceptable usernames and I'm trying to make an expression for them.
Here they are:
1-15 Characters
a-z, A-Z, 0-9, and spaces are acceptable
Must begin with a-z or A-Z
Cannot end in a space
Cannot contain two spaces in a row
This is as far as I've gotten with it.
/^[a-zA-Z]{1}([a-zA-Z0-9]|\s(?!\s)){0,14}[^\s]$/
It works, for the most part, but doesn't match a single character such as "a".
Can anyone help me out here? I'm using PCRE in PHP if that makes any difference.

Try this:
/^(?=.{1,15}$)[a-zA-Z][a-zA-Z0-9]*(?: [a-zA-Z0-9]+)*$/
The look-ahead assertion (?=.{1,15}$) checks the length and the rest checks the structure:
[a-zA-Z] ensures that the first character is an alphabetic character;
[a-zA-Z0-9]* allows any number of following alphanumeric characters;
(?: [a-zA-Z0-9]+)* allows any number of sequences of a single space (not \s that allows any whitespace character) that must be followed by at least one alphanumeric character (see PCRE subpatterns for the syntax of (?:…)).
You could also remove the look-ahead assertion and check the length with strlen.

make everything after your first character optional
^[a-zA-Z]?([a-zA-Z0-9]|\s(?!\s)){0,14}[^\s]$

The main problem of your regexp is that it needs at least two characters two have a match :
one for the [a-zA-Z]{1} part
one for the [^\s] part
Beside this problem, I see some parts of your regexp that could be improved :
The [^\s] class will match any character, except spaces : a dot or semi-colon will be accepted, try to use the [a-zA-Z0-9] class here to ensure the character is a correct one.
You can delete the {1} part at the beginning, as the regexp will match exactly one character by default

Related

How can I repeat the unicode character as the digits and characters with \d* and \w*

I have this regular expression:
\d*\w*[\x{0021}-\x{003F}]*
I want to repeat a digit, a character and a specific code point between 0021 and 003f any number of times.
I have seen that with \d*\w* you can make "a1" so the order doesn`t matter but I can only repeat the code point character at the end, how can I make that the order of that repetition doesn't matters like the digits and characters to make strings like: a1!a?23!sd2
Using \w also matches \d, so you can omit that from the character class.
Note that this part {0021}-\x{003F} also matches digits 0-9 (See the ASCII table Hx value 21-3F) so there is some overlap as well.
You could split it up in 2 unicode ranges, but that would just make the character class notation longer.
Changing it to [A-Za-z_\x{0021}-\x{003F}]+ specifies all the used ranges, but if you add the unicode flag in php, using \w matches a lot more than [A-Za-z]
To match 1 or more occurrences, you could use:
[\w\x{0021}-\x{003F}]+
See this regex demo and this regex demo.

How to check if string contains specific special characters or starting with a space? [duplicate]

I have the following requirements for validating an input field:
It should only contain alphabets and spaces between the alphabets.
It cannot contain spaces at the beginning or end of the string.
It cannot contain any other special character.
I am using following regex for this:
^(?!\s*$)[-a-zA-Z ]*$
But this is allowing spaces at the beginning. Any help is appreciated.
For me the only logical way to do this is:
^\p{L}+(?: \p{L}+)*$
At the start of the string there must be at least one letter. (I replaced your [a-zA-Z] by the Unicode code property for letters \p{L}). Then there can be a space followed by at least one letter, this part can be repeated.
\p{L}: any kind of letter from any language. See regular-expressions.info
The problem in your expression ^(?!\s*$) is, that lookahead will fail, if there is only whitespace till the end of the string. If you want to disallow leading whitespace, just remove the end of string anchor inside the lookahead ==> ^(?!\s)[-a-zA-Z ]*$. But this still allows the string to end with whitespace. To avoid this look back at the end of the string ^(?!\s)[-a-zA-Z ]*(?<!\s)$. But I think for this task a look around is not needed.
This should work if you use it with String.matches method. I assume you want English alphabet.
"[a-zA-Z]+(\\s+[a-zA-Z]+)*"
Note that \s will allow all kinds of whitespace characters. In Java, it would be equivalent to
[ \t\n\x0B\f\r]
Which includes horizontal tab (09), line feed (10), carriage return (13), form feed (12), backspace (08), space (32).
If you want to specifically allow only space (32):
"[a-zA-Z]+( +[a-zA-Z]+)*"
You can further optimize the regex above by making the capturing group ( +[a-zA-Z]+) non-capturing (with String.matches you are not going to be able to get the words individually anyway). It is also possible to change the quantifiers to make them possessive, since there is no point in backtracking here.
"[a-zA-Z]++(?: ++[a-zA-Z]++)*+"
Try this:
^(((?<!^)\s(?!$)|[-a-zA-Z])*)$
This expression uses negative lookahead and negative lookbehind to disallow spaces at the beginning or at the end of the string, and requiring the match of the entire string.
I think the problem is there's a ? before the negation of white spaces, which means it is optional
This should work:
[a-zA-Z]{1}([a-zA-Z\s]*[a-zA-Z]{1})?
at least one sequence of letters, then optional string with spaces but always ends with letters
I don't know if words in your accepted string can be seperated by more then one space. If they can:
^[a-zA-Z]+(( )+[a-zA-z]+)*$
If can't:
^[a-zA-Z]+( [a-zA-z]+)*$
String must start with letter (or few letters), not space.
String can contain few words, but every word beside first must have space before it.
Hope I helped.

Regex: Differentiating underscore(_) and dash(-)

I want to construct a pattern that identifies the valid domain name. A valid domain name has alphanumeric characters and dashes in it. The only rule is that the name should not begin or end with a dash.
I have a regular expression for the validation as ^\w((\w|-)*\w)?$
However the expression is validating the strings with underscores too (for ex.: cake_centre) which is wrong. Can anyone tell me why this is happening and how it can be corrected?
P.S.: I am using preg_match() function in PHP for checking the validation.
The metacharacter \w includes underscores, you can make a character class that will allow your listed requirements:
[a-zA-Z\d-]
or per your regex:
^[a-zA-Z\d]([a-zA-Z\d-]*[a-zA-Z\d])?$
(Also note the - position in the character class is important, a - at the start or end is the literal value. If you have it in the middle it can create a range. What special characters must be escaped in regular expressions?)
Underscores are being validated because they are part of the \w character class. If you want to exclude it, try:
/^[a-z0-9]+[a-z0-9\-]*[a-z0-9]+$/i
Here is the regexp with lookaround approach
(?<!-)([a-zA-Z0-9_]+)(?!-)
regexp pattern is created in 3 groups
First group ^(?<!-) is negetive look back to ensure that matched chars does not have dash before
Second group ([a-zA-Z0-9_]+) give matching characters
Third group (?!-) is negetive lookahead to ensure match is not ending with dash

secured regular expression that restrict specific special characters

I tried to create regular expression with specification below
any alphabetic character (at least one)
any numeric character (at least one)
no spaces
accept all special characters (except ",;&|')
^(?=.*[0-9])(?=.*[a-z])(?!.*\s)((?!.*[",;&|'])|(?=(.*\W){1,}))(?!.*[",;&|'])$
This is the one I tried.
What I can do with this?
Question is still vague in nature, please provide some examples of accepted strings.
Just to get you started you can use:
character class in a negative lookahead
Don't forget start & end anchors:
Regex:
/^(?=.*?\d)(?=.*?[a-z])(?!.*?[ ",;&|']).+$/i
This regex will match 1 or more characters that are not one of ",;&|' and atleast one digit and a-z alpgabet is required.
Live Demo: http://www.rubular.com/r/nxdi79ZcRx
In PHP use it like this:
'/^(?=.*?\d)(?=.*?[a-z])(?!.*?[ ",;&|\']).+$/i'

check the value entered by the user with regular expression in php

in my program php, I want the user doesn't enter any caracters except the alphabets
like that : "dgdh", "sgfdgdfg" but he doesn't enter the numbers or anything else like "7657" or "gfd(-" or "fd54"
I tested this function but it doesn't cover all cases :
preg_match("#[^0-9]#",$_POST['chaine'])
how can I achieve that, thank you in advance
The simplest can be
preg_match('/^[a-z]+$/i', $_POST['chaine'])
the i modifier is for case-insensitive. The + is so that at least one alphabet is entered. You can change it to * if you want to allow empty string. The anchor ^ and $ enforce that the whole string is nothing but the alphabets. (they represent the beginning of the string and the end of the string, respectively).
If you want to allow whitespace, you can use:
Whitespace only at the beginning or end of string:
preg_match('/^\s*[a-z]+\s*$/i', $_POST['chaine'])
Any where:
preg_match('/^[a-z][\sa-z]*$/i', $_POST['chaine']) // at least one alphabet
Only the space character is allowed but not other whitespace:
preg_match('/^[a-z][ a-z]*$/i', $_POST['chaine'])
Two things. Firstly, you match non-digit characters. That is obviously not the same as letter characters. So you could simply use [a-zA-Z] or [a-z] and the case-insensitive modifier instead.
Secondly you only try to find one of those characters. You don't assert that the whole string is composed of these. So use this instead:
preg_match("#^[a-z]*$#i",$_POST['chaine'])
Only match letters (no whitespace):
preg_match("#^[a-zA-Z]+$#",$_POST['chaine'])
Explanation:
^ # matches the start of the line
[a-zA-Z] # matches any letter (upper or lowercase)
+ # means the previous pattern must match at least once
$ # matches the end of the line
With whitespace:
preg_match("#^[a-zA-Z ]+$#",$_POST['chaine'])

Categories