Regular Expressions | Restrict Possible Usernames - javascript

Question
Here are some simple rules that users have to follow when creating their username.
1) Usernames can only use alpha-numeric characters.
2) The only numbers in the username have to be at the end. There can be zero or more of them at the end. Username cannot start with the number.
3) Username letters can be lowercase and uppercase.
4) Usernames have to be at least two characters long. A two-character username can only use alphabet letters as characters.
My Code
let username = "JackOfAllTrades";
let userCheck = /^(a-za-z|a-z(a-z+|\d\d+))(\d*)$/i;
let result = userCheck.test(username);
My Question
How can I fix this code?
What is it about the code that doesn't work?

Solution 1:
let username = "JackOfAllTrades";
let userCheck = /^[a-z]([0-9][0-9]+|[a-z]+\d*)$/i;
let result = userCheck.test(username);
Code Explanation
^ - start of input
[a-z] - first character is a letter
[0-9][0-9]+ - ends with two or more numbers
| - or
[a-z]+ - has one or more letters next
\d* - and ends with zero or more numbers
$ - end of input
i - ignore case of input
Solution 2:
let username = "JackOfAllTrades";
const userCheck = /^[a-z]([0-9]{2,}|[a-z]+\d*)$/i;
let result = userCheck.test(username);
Code Explanation
^ - start of input
[a-z] - first character is a letter
[0-9]{2,0} - ends with two or more numbers
| - or
[a-z]+ - has one or more letters next
\d* - and ends with zero or more numbers
$ - end of input
i - ignore case of input

Here is my solution:
/^[a-z][a-z]+$|^[a-z]+\w\d+$/i
/^ - at the beginning of the string, find
[a-z][a-z]+$ - at least 2 letters, could be more, till the end(this means that strings like test12 will not pass in this one)
| - OR (to the cases where it has more numbers and more than 2 characters
^[a-z]+ - beginning with any letter, can be more
\w - any character, can be a-z and 0-9, it is used this way to force the string to have at least 3 characters
\d+$ - ending with a chain with at least one number(if it doesn't have at least one number at the end, it will match in the first of the conditional)
/i - consider caps characters

Edit: I missed something in the OP requirements: there can be only one leading letter if the username is more than 2 characters long. So I corrected this answer accordingly, and we fundamentally get the same regex as Venkatesh's solution 2.
I supposed that you wish only non-accented characters.
With the regular expression /^[a-z]([a-z]+\d*|\d{2,})$/i (test it here), you get the following matches/failures (when testing one by one):
• Paul46: matches
• 4frank: fails
• mike: matches
• jus6tin: fails
• p87: matches
• k9: fails
• AL10: matches

Try this one:
let userCheck = /^[a-z]([a-z]+|[a-z]*[\d][\d])$/i;

let userCheck = /^[a-z]([a-z]+|[0-9]\d+)\d*$/i;
Above passes all test cases of this problem

The below solution works fine to find a username ased on the below conditions
Usernames can only use alpha-numeric characters.
The only numbers in the username have to be at the end. There can be zero or 2. more of them at the end. Username cannot start with the number.
Username letters can be lowercase and uppercase.
Usernames have to be at least two characters long. A two-character username can only use alphabet letters as characters.
let username = "JackOfAllTrades";
let userCheck = /^[a-z]+(\d\d+$|[a-z]+\d*$)/i; // Change this line
let result = userCheck.test(username);
console.log(result)
Description:
^[a-z]+ - to match one or more(+) alphabet([a-z]) in the beginning(^).
\d\d+$ - to match the ending 2 or more(\d for one and \d+ for one or more) number if only one alphabet in the beginning.
[a-z]+\d*$ - to match one or more alphabet along with 0 or more number at the end.
i - flag for ignoring letter case
| - sign to pick match both regex

Related

How to write regex to match password with rules

I'm trying to write regex to match password with following rule
Minimum length - 8 characters, if it includes a number and a lowercase letter OR 15 characters with any combination of characters
Here's my regex
^(?=.*\d[a-z]).{8,}|([a-zA-Z0-9]{15,})$
Expected result:
2232ddds - correct
ddds2222 - correct
Actual result:
2232ddds - correct
ddds2222 - incorrect
Could you help me to find a problem?
The problems are two:
The anchors only affect the alternatives they stand next to
The (?=.*\d[a-z]) lookahead requires a digit and a lowercase to appear in this order only, if there is a letter and then a digit, it won't work.
You may use
/^(?:(?=.*\d)(?=.*[a-z]).{8,}|[a-zA-Z0-9]{15,})$/
^^^|-----------------| ^ ^
See the regex demo.
If you want to make it more efficient and follow best practices use
/^(?:(?=\D*\d)(?=[^a-z]*[a-z]).{8,}|[a-zA-Z0-9]{15,})$/
Details
^ - start of string
(?: - a non-capturing group start
(?=\D*\d) - at least 1 digit
(?=[^a-z]*[a-z]) - at least 1 lowercase letter
.{8,} - any 8 or more chars other than line break chars
| - or
[a-zA-Z0-9]{15,} - 15 or more alphanumeric chars only
) - end of non-capturing group
$ - end of string.
Here a few options you can choose to build your regex:
String contains at least one:
Lower case (?=.*[a-z])
Upper case (?=.*[A-Z])
Numbers (?=.*\d)
Symbols (?=.[!##\$%\^&])
Minimal characters of string: (?=.{8,})
Your regex would be: (?=.*[a-z])(?=.*\d)(?=.{8,})|(?=.{15,})
Hope this helps!

Regular expression for an alphanumeric word start with alphabet

I have a requirement to find and return the first occurrence of the pattern from a string.
Example: Please find my model number RT21M6211SR/SS and save it
Expected output: RT21M6211SR/SS
Condition for the pattern to match
Combination of digits and alphabets
Character length between 6 to 14
May or may not contain special characters like '-' or '/'
Starts with always alphabet
What I tried, but it didn't work for 4th condition
var str = 'Please find my model number RT21M6211SR/SS and save it';
var reg = /\b(\w|\d)[\d|\w-\/]{6,14}\b/;
var extractedMNO = '';
var mg = str.match(reg) || [""];
console.log('regular match mno', mg[0]);
\w matches word characters, which includes _ and digits as well. If you only want to match alphabetical characters, use [a-z] to match the first character.
Also, because you want to match lengths of 6-14, after matching the first character, you should repeat the character set with {5,13}, so that the repeated characters plus the first character comes out to a length of 6-14 characters.
var str = 'Please find my model number RT21M6211SR/SS and save it';
console.log(str.match(/\b[a-z][a-z0-9\/-]{5,13}/gi)[2]);
But since the matched string must contain digits (and doesn't just permit digits), then you need to make sure a digit exists in the matched substring as well, which you can accomplish by using lookahead for a digit right after matching the alphabetical at the start:
var str = 'Please find my model number RT21M6211SR/SS and save it';
console.log(str.match(/\b[a-z](?=[a-z\/-]{0,12}[0-9])[a-z0-9\/-]{5,13}/gi));
// ^^^^^^^^^^^^^^^^^^^^^^^
If you want to permit other special characters, just add them to the character set(s).

regex - don't allow name to finish with hyphen

I'm trying to create a regex using javascript that will allow names like abc-def but will not allow abc-
(hyphen is also the only nonalpha character allowed)
The name has to be a minimum of 2 characters. I started with
^[a-zA-Z-]{2,}$, but it's not good enough so I'm trying something like this
^([A-Za-z]{2,})+(-[A-Za-z]+)*$.
It can have more than one - in a name but it should never start or finish with -.
It's allowing names like xx-x but not names like x-x. I'd like to achieve that x-x is also accepted but not x-.
Thanks!
Option 1
This option matches strings that begin and end with a letter and ensures two - are not consecutive so a string like a--a is invalid. To allow this case, see the Option 2.
^[a-z]+(?:-?[a-z]+)+$
^ Assert position at the start of the line
[a-z]+ Match any lowercase ASCII letter one or more times (with i flag this also matches uppercase variants)
(?:-?[a-z]+)+ Match the following one or more times
-? Optionally match -
[a-z]+ Match any ASCII letter (with i flag)
$ Assert position at the end of the line
var a = [
"aa","a-a","a-a-a","aa-aa-aa","aa-a", // valid
"aa-a-","a","a-","-a","a--a" // invalid
]
var r = /^[a-z]+(?:-?[a-z]+)+$/i
a.forEach(function(s) {
console.log(`${s}: ${r.test(s)}`)
})
Option 2
If you want to match strings like a--a then you can instead use the following regex:
^[a-z]+[a-z-]*[a-z]+$
var a = [
"aa","a-a","a-a-a","aa-aa-aa","aa-a","a--a", // valid
"aa-a-","a","a-","-a" // invalid
]
var r = /^[a-z]+[a-z-]*[a-z]+$/i
a.forEach(function(s) {
console.log(`${s}: ${r.test(s)}`)
})
You can use a negative lookahead:
/(?!.*-$)^[a-z][a-z-]+$/i
Regex101 Example
Breakdown:
// Negative lookahead so that it can't end with a -
(?!.*-$)
// The actual string must begin with a letter a-z
[a-z]
// Any following strings can be a-z or -, there must be at least 1 of these
[a-z-]+
let regex = /(?!.*-$)^[a-z][a-z-]+$/i;
let test = [
'xx-x',
'x-x',
'x-x-x',
'x-',
'x-x-x-',
'-x',
'x'
];
test.forEach(string => {
console.log(string, ':', regex.test(string));
});
The problem is that the first assertion accepts 2 or more [A-Za-z]. You will need to modify it to accept one or more character:
^[A-Za-z]+((-[A-Za-z]{1,})+)?$
Edit: solved some commented issues
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('xggg-dfe'); // Logs true
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('x-d'); // Logs true
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('xggg-'); // Logs false
Edit 2: Edited to accept characters only
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('abc'); // Logs true
Use this if you want to accept such as A---A as well :
^(?!-|.*-$)[A-Za-z-]{2,}$
https://regex101.com/r/4UYd9l/4/
If you don't want to accept such as A---A do this:
^(?!-|.*[-]{2,}.*|.*-$)[A-Za-z-]{2,}$
https://regex101.com/r/qH4Q0q/4/
So both will accept only word starting from two characters of the pattern [A-Za-z-] and not start or end (?!-|.*-$) (negative lookahead) with - .
Try this /([a-zA-Z]{1,}-[a-zA-Z]{1,})/g
I suggest the following :
^[a-zA-Z][a-zA-Z-]*[a-zA-Z]$
It validates :
that the matched string is at least composed of two characters (the first and last character classes are matched exactly once)
that the first and the last characters aren't dashes (the first and last character classes do not include -)
that the string can contain dashes and be greater than 2 characters (the second character class includes dashes and will consume as much characters as needed, dashes included).
Try it online.
^(?=[A-Za-z](?:-|[A-Za-z]))(?:(?:-|^)[A-Za-z]+)+$
Asserts that
the first character is a-z
the second is a-z or hyphen
If this matches
looks for groups of one or more letters prefixed by a hyphen or start of string, all the way to end of string.
You can also use the I switch to make it case insensitive.

Removes all after the first block of numbers

I'm trying to write code that removes all after the first block of numbers and text.Do you have any idea how to do this.
string = '009EPMT18$MBS'
the expected result
string = '009EPMT'
You'll need regex to do that. It's a string analysis syntax common in many languages. There are many regular expressions which would do what you want, here's one:
var myRegex = /^[0-9]+[a-zA-Z]+/;
^ means that the search must begin at the start of the string.
[0-9] means that right after the beginning, there must be characters in the 0 to 9 range.
+ means there must be one or more of the previous condition, meaning there must be one or more digits.
[a-zA-Z] means there must be any character in the range a to z or A to Z. This won't include accented characters and letters from other alphabets though.
Calling .exec(string) on a regex returns an array of found strings in the passed string.
You were on the right track, the letters were just missing from your pattern:
var s = '009EPMT18$MBS';
var result;
var m = s.match(/^\d+[A-Z]+/); // first numbers and uppercase text
if (m) result = m[0]; // result = "009EPMT"
Regex explanation: beginning of string ^ followed by 1 or more digits \d+ followed by 1 or more letters from A to Z [A-Z]+. Note that lowercase characters will not match.

validating variable in javascript

Hi i have a field in php that will be validated in javascript using i.e for emails
var emailRegex = /^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$/;
What i'm after is a validation check which will look for the
first letter as a capital Q
then the next letters can be numbers only
then followed by a .
then two numbers only
and then an optional letter
i.e Q100.11 or Q100.11a
I must admit i look at the above email validation check and i have no clue how it works but it does ;)
many thanks for any help on this
Steve
The ^ marks the beginning of the string, $ matches the end of the string. In other words, the whole string should exactly match this regular expression.
[\w-\.]+: I think you wanted to match letters, digits, dots and - only. In that case, the - should be escaped (\-): [\w\-\.]+. The plus-sign makes is match one or more times.
#: a literal # match
([\w-]+\.)+ letters, digits and - are allowed one or more times, with a dot after it (between the parentheses). This may occur several times (at least once).
[\w-]{2,4}: this should match the TLD, like com, net or org. Because a TLD can only contain letters, it should be replaced by [a-z]{2,4}. This means: lowercase letters may occur two till four times. Note that the TLD can be longer than 4 characters.
An regular expression which should follow the next rules:
a capital Q (Q)
followed by one or more occurrences of digits (\d+)
a literal dot (.)
two digits (\d{2})
one optional letter ([a-z]?)
Result:
var regex = /Q\d+\.\d{2}[a-z]?/;
If you need to match strings case-insensitive, add the i (case-insensitive) modifier:
var regex = /Q\d+\.\d{2}[a-z]?/i;
Validating a string using a regexp can be done in several ways, one of them:
if (regex.test(str)) {
// success
} else {
// no match
}
var emailRegex = /^Q\d+\.\d{2}[a-zA-Z]?#([\w-]+\.)+[a-zA-Z]+$/;
var str = "Q100.11#test.com";
alert(emailRegex.test(str));
var regex = /^Q[0-9]+\.[0-9]{2}[a-z]?$/;
+ means one or more
the period must be escaped - \.
[0-9]{2} means 2 digits, same as \d{2}
[a-z]? means 0 or 1 letter
You can check your regex at http://regexpal.com/

Categories