Regex validation doesn't work as expected - javascript

var validatePassword = function(password) {
var upper = new RegExp(/^(?=.*[A-Z]).+$/),
lower = new RegExp(/^(?=.*[a-z]).+$/),
symbols = new RegExp(/^(?=.*(_|[^\w])).+$/),
numbers = new RegExp(/^(?=.*\d).+$/);
if((upper.test(password) && lower.test(password)) || (upper.test(password) && numbers.test(password)) || (upper.test(password) && symbols.test(password)) || (lower.test(password) && numbers.test(password)) || (lower.test(password) && symbols.test(password)))
{
return true;
}
else
{
alert('Invalid password')
}
}
validatePassword('Foo1!');
});
it only return true if any value is entered if i only enter one it returns me true

You should do:
var upper = new RegExp(/^(?=.*[A-Z]).+$/),
lower = new RegExp(/^(?=.*[a-z]).+$/),
symbols = new RegExp(/^(?=.*(_|[^\w])).+$/),
numbers = new RegExp(/^(?=.*\d).+$/);
to:
var upper = /^(?=.*[A-Z]).+$/,
lower = /^(?=.*[a-z]).+$/,
symbols = /^(?=.*(_|[^\w])).+$/,
numbers = /^(?=.*\d).+$/;
Your regex is already a regex. You don't need to use new RegExp("patter","flag");

Let's simplify the logic first
var upper = new RegExp(/^(?=.*[A-Z]).+$/),
lower = new RegExp(/^(?=.*[a-z]).+$/),
symbols = new RegExp(/^(?=.*(_|[^\w])).+$/),
numbers = new RegExp(/^(?=.*\d).+$/);
Above can be simplified
var upper = /[A-Z]/, // means it contains uppercase
lower = /[a-z]/, // means it contains lowercase
symbols = /[\W_]/, // means it contains non-word character or underscore
numbers = /\d/; // means it contains number
Also here
// means must have (upper AND lower) OR ((upper OR lower) AND (symbol OR number))
if(
(upper.test(password) && lower.test(password)) ||
(upper.test(password) && numbers.test(password)) ||
(upper.test(password) && symbols.test(password)) ||
(lower.test(password) && numbers.test(password)) ||
(lower.test(password) && symbols.test(password))
)
Above can be simplified
// means must have (upper AND lower) OR ((upper OR lower) AND (symbol OR number))
if(
(upper.test(password) && lower.test(password)) ||
((upper.test(password) || lower.test(password)) &&
(symbols.test(password) || symbols.test(password)))
)
Since it can be (upper AND lower) only
upper.test(password) && lower.test(password)
It can be tested with
var upandlow = /[a-z][A-Z]|[A-Z][a-z]/;
Since it must have (upper OR lower), then it can also be checked in ONE step
var upperlower = /[a-zA-Z]/; // means it contains uppercase OR lowercase
Since it must have (symbol OR number), then it can also be checked in ONE step
var symbolsnumbers = /[\d\W_]/; // means it contains number OR non-word OR underscore
Now the whole function can be simplified
var validatePassword = function(password) {
var upandlow = /[a-z][A-Z]|[A-Z][a-z]/,
upperlower = /[a-zA-Z]/,
symbolsnumbers = /[\d\W_]/;
if (
upandlow.test(password) ||
(upperlower.test(password) && symbolsnumbers.test(password))) {
console.log('true');
return true;
}
else {
//alert('Invalid password');
console.log('Invalid');
}
}
validatePassword('Foo!');
Here is the fiddle
Good luck
:)

Based on your comment I've updated my answer:
The password needs to match at least two out of 4 conditions and have 8 characters to be true
var validatePassword = function(password) {
var numero = 0;
//check if a digit is present
if(/(?=.*?[\d]).*$/.test(password)) {
numero++;
}
//check if a uppercase letter is present
if(/(?=.*?[A-Z]).*$/.test(password)) {
numero++;
}
//check if a lowercase letter is present
if(/(?=.*?[a-z]).*$/.test(password)) {
numero++;
}
//check if a special character is present
if(/(?=.*?(_|[^\w])).*$/.test(password)) {
numero++;
}
//check if at least 8 characters are present
if (/^(?=.{8,}).*$/.test(password)) {
var length = true;
}
if( numero>=2 && length){
alert('Valid password');
console.log(numero);
return true;
}
else
{
alert('Invalid password');
console.log(numero);
}
}
validatePassword('foo4ogD!');
http://jsfiddle.net/tuga/S57Bb/4/

Related

Else if statements with toUpperCase(), toLowerCase() and Number.isInteger() [duplicate]

How can I test if a letter in a string is uppercase or lowercase using JavaScript?
The answer by josh and maleki will return true on both upper and lower case if the character or the whole string is numeric. making the result a false result.
example using josh
var character = '5';
if (character == character.toUpperCase()) {
alert ('upper case true');
}
if (character == character.toLowerCase()){
alert ('lower case true');
}
another way is to test it first if it is numeric, else test it if upper or lower case
example
var strings = 'this iS a TeSt 523 Now!';
var i=0;
var character='';
while (i <= strings.length){
character = strings.charAt(i);
if (!isNaN(character * 1)){
alert('character is numeric');
}else{
if (character == character.toUpperCase()) {
alert ('upper case true');
}
if (character == character.toLowerCase()){
alert ('lower case true');
}
}
i++;
}
if (character == character.toLowerCase())
{
// The character is lowercase
}
else
{
// The character is uppercase
}
The problem with the other answers is, that some characters like numbers or punctuation also return true when checked for lowercase/uppercase.
I found this to work very well for it:
function isLowerCase(str)
{
return str == str.toLowerCase() && str != str.toUpperCase();
}
This will work for punctuation, numbers and letters:
assert(isLowerCase("a"))
assert(!isLowerCase("Ü"))
assert(!isLowerCase("4"))
assert(!isLowerCase("_"))
To check one letter just call it using isLowerCase(str[charIndex])
const isUpperCase = (string) => /^[A-Z]*$/.test(string)
then :
isUpperCase('A') // true
isUpperCase('a') // false
This will log true if character is uppercase letter, and log false in every other case:
var letters = ['a', 'b', 'c', 'A', 'B', 'C', '(', ')', '+', '-', '~', '*'];
​​​for (var ​i = 0; i<letters.length; i++) {
if (letters[i] === letters[i].toUpperCase()
&& letters[i] !== letters[i].toLowerCase()) {
console.log(letters[i] + ": " + true);
} else {
console.log(letters[i] + ": " + false);
}
}​
You may test it here: http://jsfiddle.net/Axfxz/ (use Firebug or sth).
​​​for (var ​i = 0; i<letters.length; i++) {
if (letters[i] !== letters[i].toUpperCase()
&& letters[i] === letters[i].toLowerCase()) {
console.log(letters[i] + ": " + true);
} else {
console.log(letters[i] + ": " + false);
}
}​
and this is for lowercase:).
function isUpperCase(myString) {
return (myString == myString.toUpperCase());
}
function isLowerCase(myString) {
return (myString == myString.toLowerCase());
}
You could utilize a regular expression test and the toUpperCase method:
String.prototype.charAtIsUpper = function (atpos){
var chr = this.charAt(atpos);
return /[A-Z]|[\u0080-\u024F]/.test(chr) && chr === chr.toUpperCase();
};
// usage (note: character position is zero based)
'hi There'.charAtIsUpper(3); //=> true
'BLUE CURAÇAO'.charAtIsUpper(9); //=> true
'Hello, World!'.charAtIsUpper(5); //=> false
See also
function isCapital(ch){
return ch.charCodeAt() >= 65 && ch.charCodeAt() <= 90;
}
More specifically to what is being asked. Pass in a String and a position to check. Very close to Josh's except that this one will compare a larger string. Would have added as a comment but I don't have that ability yet.
function isUpperCase(myString, pos) {
return (myString.charAt(pos) == myString.charAt(pos).toUpperCase());
}
function isLowerCase(myString, pos) {
return (myString.charAt(pos) == myString.charAt(pos).toLowerCase());
}
A good answer to this question should be succinct, handle unicode correctly, and deal with empty strings and nulls.
function isUpperCase(c) {
return !!c && c != c.toLocaleLowerCase();
}
This approach deals with empty strings and nulls first, then ensures that converting the given string to lower case changes its equality. This ensures that the string contains at least one capital letter according to the current local's capitalisation rules (and won't return false positives for numbers and other glyphs that don't have capitalisation).
The original question asked specifically about testing the first character. In order to keep your code simple and clear I'd split the first character off the string separately from testing whether it's upper case.
You can also use a regular expression to explicitly detect uppercase roman alphabetical characters.
isUpperCase = function(char) {
return !!/[A-Z]/.exec(char[0]);
};
EDIT: the above function is correct for ASCII/Basic Latin Unicode, which is probably all you'll ever care about. The following version also support Latin-1 Supplement and Greek and Coptic Unicode blocks... In case you needed that for some reason.
isUpperCase = function(char) {
return !!/[A-ZÀ-ÖØ-ÞΆΈ-ΏΑ-ΫϢϤϦϨϪϬϮϴϷϹϺϽ-Ͽ]/.exec(char[0]);
};
This strategy starts to fall down if you need further support (is Ѭ uppercase?) since some blocks intermix upper and lowercase characters.
There's a really simple answer, which nobody else has mentioned:
function isLowerCase(str) {
return str !== str.toUpperCase();
}
If str.toUpperCase() does not return the same str, it has to be lower case. To test for upper case you change it to str !== str.toLowererCase().
Unlike some other answers, it works correctly on non-alpha characters (returns false) and it works for other alphabets, accented characters etc.
This is straightforward, readable solution using a simple regex.
// Get specific char in string
const char = string.charAt(index);
const isLowerCaseLetter = (/[a-z]/.test(char));
const isUpperCaseLetter = (/[A-Z]/.test(char));
I believe this is the easiest solution.. You can use onchange handler in input field .. to do the validation
const isValid = e.target.value === e.target.value.toLowerCase()
if (isValid) {
//Do something
} else {
//Do something
}
With modern browsers you can use regexp and unicode property tests e.g.
/\p{Lu}/u.test("A") // is true
/\p{Lu}/u.test("Å") // is true
/\p{Lu}/u.test("a1å") // is false
More info here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
List of general categories here:
https://unicode.org/reports/tr18/#General_Category_Property
You can also use this, it will check the string for lower and uppercase
var s = "a"
if(/[a-z]/.test(s)){
alert ('lower case true');
}
if(/[A-Z]/.test(s)) {
alert ('upper case true');
}
The best way is to use a regular expression, a ternary operator, and the built in .test() method for strings.
I leave you to Google the ins and outs of regular expressions and the test method for strings (they're easy to find), but here we'll use it to test your variable.
/[a-z]/i.test(your-character-here)
This will return TRUE of FALSE based on whether or not your character matches the character set in the regular expression. Our regular expression checks for all letters a-z /[a-z]/ regardless of their case thanks to the i flag.
So, a basic test would be:
var theAnswer = "";
if (/[a-z]/i.test(your-character-here)) {
theAnswer = "It's a letter."
}
Now we need to determine if it's upper or lower case. So, if we remove the i flag from our regular expression, then our code above will test for lower case letters a-z. And if we stick another if statement in the else of our first if statement, we can test for upper case too by using A-Z. Like this:
var theAnswer = "";
if (/[a-z]/.test(your-character-here)) {
theAnswer = "It's a lower case letter."
} else if (/[A-Z]/.test(your-character-here)) {
theAnswer = "It's an upper case letter.";
}
And just in case it's not a letter, we can add a final else statement:
var theAnswer = "";
if (/[a-z]/.test(your-character-here)) {
theAnswer = "It's a lower case letter."
} else if (/[A-Z]/.test(your-character-here)) {
theAnswer = "It's an upper case letter.";
} else {
theAnswer = "It's not a letter."
}
The above code would work. But it's kinda ugly. Instead, we can use a "ternary operator" to replace our if-else statements above. Ternary operators are just shorthand simple ways of coding an if-else. The syntax is easy:
(statement-to-be-evaluated) ? (code-if-true) : (code-if-false)
And these can be nested within each other, too. So a function might look like:
var theAnswer = "";
function whichCase(theLetter) {
theAnswer = /[a-z]/.test(theLetter) ? "It's lower case." : "";
theAnswer = /[A-Z]/.test(theLetter) ? "It's upper case." : "";
return(theAnswer);
}
The above code looks good, but won't quite work, because if our character is lower case, theAnswer gets set to "" when it test for uppercase, so lets nest them:
var theAnswer = "";
function whichCase(theLetter) {
theAnswer = /[a-z]/.test(theLetter) ? "It's lower case." : (/[A-Z]/.test(theLetter) ? "It's upper case." : "It's not a letter.");
return(theAnswer);
}
That will work great! But there's no need to have two seperate lines for setting the variable theAnswer and then returning it. And we should be using let and const rather than var (look those up if you're not sure why). Once we make those changes:
function whichCase(theLetter) {
return(/[A-Z]/.test(theLetter) ? "It's upper case." : (/[a-z]/.test(theLetter) ? "It's lower case." : "It's not a letter."));
}
And we end up with an elegant, concise piece of code. ;)
See my comment on the chosen answer. Other solutions that limit to the ASCII table or use the actual character literals completely ignore Unicode and the several hundred other characters there that have case.
This code will set the caseGroup variable to:
1 for Upper Case
-1 for Lower Case
0 for Without Case
var caseGroup = (character.toLowerCase() == character.toUpperCase() ? 0 : (character == character.toUpperCase() ? 1 : -1));
You could bake that into something like this...
function determineCase(character) {
return (character.toLowerCase() == character.toUpperCase() ? 0 : (character == character.toUpperCase() ? 1 : -1));
}
function isUpper(character) {
return determineCase(character) == 1;
}
function isLower(character) {
return determineCase(character) == -1;
}
function hasCase(character) {
return determineCase(character) != 0;
}
function solution(s) {
var c = s[0];
if (c == c.toUpperCase() && !(c >= '0' && c <= '9') &&(c >='A' && c <= 'Z')) {
return 'upper';
} else if (c == c.toLowerCase() && !(c >= '0' && c <= '9') &&(c >='a' && c <= 'z')){
return 'lower';
} else if (c >= '0' && c <= '9'){
return 'digit'
} else {
return 'other'
}
}
var str1= (solution('A')) // upper
var str2 = solution('b') // lower
var str3 = solution('1') // digit
var str4 = solution('_') // other
console.log(`${str1} ${str2} ${str3} ${str4}`)
You can test if your array has an upper case or lower case string by using the match method and regex, below is just a basic foundation to start your test
var array = ['a', 'b', 'c', 'A', 'B', 'C', '(', ')', '+', '-', '~', '*'];
var character = array.join('')
console.log(character)
var test = function(search){
upperCase = search.match(/[A-Z]/g)
console.log(upperCase)
lowerCase = search.match(/[a-z]/g)
console.log(lowerCase)
}
test(character)
This is how I did it recently:
1) Check that a char/string s is lowercase
s.toLowerCase() == s && s.toUpperCase() != s
2) Check s is uppercase
s.toUpperCase() == s && s.toLowerCase() != s
Covers cases where s contains non-alphabetic chars and diacritics.
function checkCharType (charToCheck) {
// body...
var returnValue = "O";
var charCode = charToCheck.charCodeAt(0);
if(charCode >= "A".charCodeAt(0) && charCode <= "Z".charCodeAt(0)){
returnValue = "U";
}else if (charCode >= "a".charCodeAt(0) &&
charCode <= "z".charCodeAt(0) ){
returnValue = "L";
}else if (charCode >= "0".charCodeAt(0) &&
charCode <= "9".charCodeAt(0) ) {
returnValue = "N";
}
return returnValue;
}
var myString = prompt("Enter Some text: ", "Hello world !");
switch (checkCharType(myString)) {
case "U":
// statements_1
document.write("First character was upper case");
break;
case "L":
document.write("First character was a lower case");
break;
case "N":
document.write("First character was a number");
break
default:
// statements_def
document.write("First character was not a character or a number");
break;
}
Define a Function checkCharType().By declaring the variable returnValue and initialising it to the Character "O" to indicate it's Some other value.
U for uppercase; L for Lowercase ; N for number
Use the charCodeAt() method to get the character code of the first character.
Using if Statement , which check within what range of values the character code falls.
If it falls between the character codes for A and Z, Its Uppercase,
character code between a and z ,Its Lowercase. and so on.
"A".charCode(0)
var myChar = new String("A");
myChar.charCodeAt(0);
"A" : number code "65“
Check the String
This checks the ENTIRE string, not just the first letter. I thought I'd share it with everyone here.
Here is a function that uses a regular expression to test against the letters of a string; it returns true if the letter is uppercase (A-Z). We then reduce the true/false array to a single value. If it is equal to the length of the string, that means all the letters passed the regex test, which means the string is uppercase. If not, the string is lowercase.
const isUpperCase = (str) => {
let result = str
.split('')
.map(letter => /[A-Z]/.test(letter))
.reduce((a, b) => a + b);
return result === str.length;
}
console.log(isUpperCase('123')); // false
console.log('123' === '123'.toUpperCase()); // true
This question has clearly been answered a number of times, but i thought i'd share my solution as I haven't seen it in the given answers.
var lower_case = function(letter){
lowers = "abcdefghijklmnopqrstuvwxyz";
return letter === letter.toLowerCase() && lowers.indexOf(letter) >= 0
};
var upper_case = function(letter){
uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return letter === letter.toUpperCase() && uppers.indexOf(letter) >= 0
};
2¢
function checkCase(c){
var u = c.toUpperCase();
return (c.toLowerCase() === u ? -1 : (c === u ? 1 : 0));
};
Based on Sonic Beard comment to the main answer. I changed the logic in the result:
0: Lowercase
1: Uppercase
-1: neither
Assuming that a string is only considered to not be all uppercase if at least one lowercase letter is present, this works fine. I understand it's not concise and succinct like everybody else tried to do, but does it works =)
function isUpperCase(str) {
for (var i = 0, len = str.length; i < len; i++) {
var letter = str.charAt(i);
var keyCode = letter.charCodeAt(i);
if (keyCode > 96 && keyCode < 123) {
return false;
}
}
return true;
}
I need to test against a string of any character (including white space, marks, numbers, unicode characters...). Because white space, numbers, marks... will be the same in both upper case and lower case, and I want to find real upper case letters, I do this:
let countUpperCase = 0;
let i = 0;
while (i <= string.length) {
const character = string.charAt(i);
if (character === character.toUpperCase() && character !== character.toLowerCase()) {
countUpperCase++;
}
i++;
}
Simply check the ASCII value
// IsLower verify that a string does not contains upper char
func IsLower(str string) bool {
for i := range str {
ascii := int(str[i])
if ascii < 91 && ascii > 64 {
return false
}
}
return true
}
Another way is to compare the character with an empty object, i don't really know's why it works, but it works :
for (let i = 1; i <= 26; i++) {
const letter = (i + 9).toString(36).toUpperCase();
console.log('letter', letter, 'is upper', letter<{}); // returns true
}
for (let i = 1; i <= 26; i++) {
const letter = (i + 9).toString(36);
console.log('letter', letter, 'is upper', letter<{}); // returns false
}
so in a function :
function charIsUpper(character) {
return character<{};
}
EDIT: it doesn't work with accents and diacritics, so it's possible to remove it
function charIsUpper(character) {
return character
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')<{};
}
One I use (notice this doesnt make "TestString" as "T est String" or " Test String").
function seperateCapitalised(capitalisedString) {
if (typeof capitalisedString !== "string" || capitalisedString.length === 0)
return capitalisedString;
var newStr = capitalisedString[0];
for (var i = 1; i < capitalisedString.length; i++) {
var char = capitalisedString[i];
if (char === char.toUpperCase() && isNaN(char)) {
newStr += ' ' + char;
}
else {
newStr += char;
}
}
return newStr;
}

Validating Password has a digit

So everything works in the following code, except for the validation of whether or not a password has a numerical digit. Can anyone see what may be wrong with my code here? It's acting like my password passes the test for numerical digits when it doesn't.
// Too short
//var password = "pass";
// Contains a space
// password = "Contains space";
// Doesn't use a digit
password = "my-password";
// Repeats first and last 3 chars
//password = "abc123abc";
// Strong password
// password = "StrongPassword1";
// See if function returns an error message or not
var message = testPassword(password);
if (message) {
console.log(message);
}
else {
console.log("Password accepted.");
}
function testPassword(password) {
var n = password;
// Returns true if n is a string with a single digit, false otherwise
var hasDigit = function isSingleDigit(n) {
var unicodeValue = n.charCodeAt(0);
return n.length === 1 && unicodeValue >= 48 && unicodeValue <= 57;
};
if (password.length < 6){
return "Password must be at least 6 characters.";
}
if (password.indexOf(" ") != -1){
return "Password may not contain a space.";
}
if (hasDigit === false){
return "Password must have at least one digit.";
}
if (password.substr(0, 3) === password.substr(-3)){
return "The password may not begin and end with the same 3 characters.";
}
// Everything is good
return "";
}
Console output:
Password accepted.
EDIT: Here was the fix. Thanks awesome community!
var n = password;
// Returns true if n is a string with a single digit, false otherwise
function isSingleDigit(n) {
var unicodeValue = n.charCodeAt(0);
return n.length === 1 && unicodeValue >= 48 && unicodeValue <= 57;
}
var hasDigit = isSingleDigit(n);
The variable hasDigit has the definition of the function itself and not the return value since it was never called.
Change your if statement to
if (hasDigit(n) === false){
return "Password must have at least one digit.";
}
Edit
However, I don't think the function would still work correctly as this function would only return true if the passwordis a single digit as opposed to a string containing at least one digit.

Javascript: Validation for special characters

I'm working on some validations and can't seem to wrap my head around checking for special chars, none should be used. Currently I grab the value, make an array and check for uppercase and numbers. I need a way to check for special chars as well. Another small issue I found is that it passes an uppercase when a number is entered. Just looking for some direction on how to tackle this.
$('.tooltip').on({
focusin: function(){ //make
var top = $(this).offset().top
var left = $(this).offset().left + $(this).outerWidth()
$('.tip').remove()
$('body').append("<div class='tip' style='top:"+ top +"px;left:"+left+"px;'><div class='arrow'></div></div>")
$('.tip').animate({width: 'show', opacity: 'show'})
$(tipContent).appendTo('.tip')
},
focusout: function(){ //remove
$('.tip').fadeOut(function(){$(this).remove()})
},
keyup: function(){ if (event.keyCode == 16) return //validate
var val = $(this).val()
validate(val.split(""), val);
},
})
function validate(letters, val){
for (var i = 0; i < letters.length; i++){
if( letters[i] === letters[i].toUpperCase() ) { //uppercase check
console.log(letters[i] + ": " + 'Uppercase Passed');
}else{console.log('Uppercase Failed');
}
if( letters.length >= 9 ) { //min limit
console.log(letters[i] + ": " + 'Minimum Limit Passed');
}else{console.log('Minimum Limit Failed');
}
if( parseInt(letters[i]) > 0 ) { //number check
console.log(parseInt(letters[i]) + ' passed');
}else{console.log('at least 1 char failed');
}
}
}
An option might be to use regular expressions, which make your requirements easy to formulate:
function validate(value) {
var regex = /^[A-Z0-9]*$/; // consist only of uppercase letters and digits
var digit = /\d/; // contains a digit
if (regex.test(value) && digit.test(value) && value.length >= 9)
console.log("Test passed");
else
console.log("Test failed");
}
You even could combine them to one regex:
function validate(value) {
return /^(?=.*\d)[A-Z0-9]{9,}$/.test(value);
// | | | |
// string / | consists \ string end
// beginning | of only
// / upper alphabet letters and numbers,
// somewhere ahead at least 9 of them
// comes a digit
}
OK, if you need these steps separately, we should be able to do that. To recognice uppercase letters we just could use the regex [A-Z], but then umlauts etc wouldn't be recognized. If you handled them as special chars, we can easily use this regex:
/^(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]).{9,}$/
| | |
digit uppercase special char
If you don't want that (or the same regexes applied as single-steps), we can test for special characters with the following condition: It is not upper- or lower-caseable, and it is not a digit.
function validation(value) {
var uc = false,
lc = false,
sc = false,
di = false,
len = value.length;
for (var i=0; i<len; i++) {
var letter = value.charAt(i),
isUpper = letter.toUppercase() == letter,
isLower = letter.toLowercase() == letter;
if (isUpper && !isLower)
uc = true;
else if (isLower && !isUpper)
uc = true;
else // isLower && isUpper - no alphabetic character
if (/\d/.test(letter))
di = true;
else
sc = true;
}
return {
someUppercase: uc,
someLowercase: lc,
someSpecial: sc,
someDigit: di,
length: len,
longEnough: len >= 9
};
}

Best way to alphanumeric check in JavaScript

What is the best way to perform an alphanumeric check on an INPUT field in JSP? I have attached my current code
function validateCode() {
var TCode = document.getElementById("TCode").value;
for (var i = 0; i < TCode.length; i++) {
var char1 = TCode.charAt(i);
var cc = char1.charCodeAt(0);
if ((cc > 47 && cc < 58) || (cc > 64 && cc < 91) || (cc > 96 && cc < 123)) {
} else {
alert("Input is not alphanumeric");
return false;
}
}
return true;
}
The asker's original inclination to use str.charCodeAt(i) appears to be faster than the regular expression alternative. In my test on jsPerf the RegExp option performs 66% slower in Chrome 36 (and slightly slower in Firefox 31).
Here's a cleaned-up version of the original validation code that receives a string and returns true or false:
function isAlphaNumeric(str) {
var code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)) { // lower alpha (a-z)
return false;
}
}
return true;
};
Of course, there may be other considerations, such as readability. A one-line regular expression is definitely prettier to look at. But if you're strictly concerned with speed, you may want to consider this alternative.
You can use this regex /^[a-z0-9]+$/i
Check it with a regex.
Javascript regexen don't have POSIX character classes, so you have to write character ranges manually:
if (!input_string.match(/^[0-9a-z]+$/))
show_error_or_something()
Here ^ means beginning of string and $ means end of string, and [0-9a-z]+ means one or more of character from 0 to 9 OR from a to z.
More information on Javascript regexen here:
https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
You don't need to do it one at a time. Just do a test for any that are not alpha-numeric. If one is found, the validation fails.
function validateCode(){
var TCode = document.getElementById('TCode').value;
if( /[^a-zA-Z0-9]/.test( TCode ) ) {
alert('Input is not alphanumeric');
return false;
}
return true;
}
If there's at least one match of a non alpha numeric, it will return false.
To match all Unicode letters and numbers you can use a Unicode regex:
const alphanumeric = /^[\p{L}\p{N}]*$/u;
const valid = "Jòhn꠵Çoe日本語3rd"; // <- these are all letters and numbers
const invalid = "JohnDoe3rd!";
console.log(valid.match(alphanumeric));
console.log(invalid.match(alphanumeric));
In the above regex the u flag enables Unicode mode. \p{L} is short for \p{Letter} and \p{N} is short for \p{Number}. The square brackets [] surrounding them is a normal character class, meaning that a character must be either a letter or a number (in this context). The * is "zero or more", you can change this into + (one or more) if you don't want to allow empty strings .^/$ matches the start/end of the string.
The above will suffice most cases, but might match more than you want. You might not want to match Latin, Arabic, Cyrillic, etc. You might only want to match Latin letters and decimal numbers.
const alphanumeric = /^[\p{sc=Latn}\p{Nd}]*$/u;
const valid = "JòhnÇoe3rd";
const invalid = "Jòhn꠵Çoe日本語3rd";
console.log(valid.match(alphanumeric));
console.log(invalid.match(alphanumeric));
\p{sc=Latn} is short for \p{Script=Latin}. \p{Nd} is short for \p{Decimal_Number} and matches decimals. The difference with \d is that \p{Nd} does not only match 5, but also 𝟓, 5 and possibly more.
Checkout the regex Unicode documentation for details, available \p options are linked on the documentation page.
Note that the u flag is not supported by Internet Explorer.
I would create a String prototype method:
String.prototype.isAlphaNumeric = function() {
var regExp = /^[A-Za-z0-9]+$/;
return (this.match(regExp));
};
Then, the usage would be:
var TCode = document.getElementById('TCode').value;
return TCode.isAlphaNumeric()
Here are some notes: The real alphanumeric string is like "0a0a0a0b0c0d" and not like "000000" or "qwertyuio".
All the answers I read here, returned true in both cases. This is not right.
If I want to check if my "00000" string is alphanumeric, my intuition is unquestionably FALSE.
Why? Simple. I cannot find any letter char. So, is a simple numeric string [0-9].
On the other hand, if I wanted to check my "abcdefg" string, my intuition
is still FALSE. I don't see numbers, so it's not alphanumeric. Just alpha [a-zA-Z].
The Michael Martin-Smucker's answer has been illuminating.
However he was aimed at achieving better performance instead of regex. This is true, using a low level way there's a better perfomance. But results it's the same.
The strings "0123456789" (only numeric), "qwertyuiop" (only alpha) and "0a1b2c3d4f4g" (alphanumeric) returns TRUE as alphanumeric. Same regex /^[a-z0-9]+$/i way.
The reason why the regex does not work is as simple as obvious. The syntax [] indicates or, not and.
So, if is it only numeric or if is it only letters, regex returns true.
But, the Michael Martin-Smucker's answer was nevertheless illuminating. For me.
It allowed me to think at "low level", to create a real function that unambiguously
processes an alphanumeric string. I called it like PHP relative function ctype_alnum (edit 2020-02-18: Where, however, this checks OR and not AND).
Here's the code:
function ctype_alnum(str) {
var code, i, len;
var isNumeric = false, isAlpha = false; // I assume that it is all non-alphanumeric
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
switch (true) {
case code > 47 && code < 58: // check if 0-9
isNumeric = true;
break;
case (code > 64 && code < 91) || (code > 96 && code < 123): // check if A-Z or a-z
isAlpha = true;
break;
default:
// not 0-9, not A-Z or a-z
return false; // stop function with false result, no more checks
}
}
return isNumeric && isAlpha; // return the loop results, if both are true, the string is certainly alphanumeric
}
And here is a demo:
function ctype_alnum(str) {
var code, i, len;
var isNumeric = false, isAlpha = false; //I assume that it is all non-alphanumeric
loop1:
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
switch (true){
case code > 47 && code < 58: // check if 0-9
isNumeric = true;
break;
case (code > 64 && code < 91) || (code > 96 && code < 123): //check if A-Z or a-z
isAlpha = true;
break;
default: // not 0-9, not A-Z or a-z
return false; //stop function with false result, no more checks
}
}
return isNumeric && isAlpha; //return the loop results, if both are true, the string is certainly alphanumeric
};
$("#input").on("keyup", function(){
if ($(this).val().length === 0) {$("#results").html(""); return false};
var isAlphaNumeric = ctype_alnum ($(this).val());
$("#results").html(
(isAlphaNumeric) ? 'Yes' : 'No'
)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input">
<div> is Alphanumeric?
<span id="results"></span>
</div>
This is an implementation of Michael Martin-Smucker's method in JavaScript.
// On keypress event call the following method
function AlphaNumCheck(e) {
var charCode = (e.which) ? e.which : e.keyCode;
if (charCode == 8) return true;
var keynum;
var keychar;
var charcheck = /[a-zA-Z0-9]/;
if (window.event) // IE
{
keynum = e.keyCode;
}
else {
if (e.which) // Netscape/Firefox/Opera
{
keynum = e.which;
}
else return true;
}
keychar = String.fromCharCode(keynum);
return charcheck.test(keychar);
}
Further, this article also helps to understand JavaScript alphanumeric validation.
In a tight loop, it's probably better to avoid regex and hardcode your characters:
const CHARS = new Set("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
function isAlphanumeric(char) {
return CHARS.has(char);
}
To check whether input_string is alphanumeric, simply use:
input_string.match(/[^\w]|_/) == null
If you want a simplest one-liner solution, then go for the accepted answer that uses regex.
However, if you want a faster solution then here's a function you can have.
console.log(isAlphaNumeric('a')); // true
console.log(isAlphaNumericString('HelloWorld96')); // true
console.log(isAlphaNumericString('Hello World!')); // false
/**
* Function to check if a character is alpha-numeric.
*
* #param {string} c
* #return {boolean}
*/
function isAlphaNumeric(c) {
const CHAR_CODE_A = 65;
const CHAR_CODE_Z = 90;
const CHAR_CODE_AS = 97;
const CHAR_CODE_ZS = 122;
const CHAR_CODE_0 = 48;
const CHAR_CODE_9 = 57;
let code = c.charCodeAt(0);
if (
(code >= CHAR_CODE_A && code <= CHAR_CODE_Z) ||
(code >= CHAR_CODE_AS && code <= CHAR_CODE_ZS) ||
(code >= CHAR_CODE_0 && code <= CHAR_CODE_9)
) {
return true;
}
return false;
}
/**
* Function to check if a string is fully alpha-numeric.
*
* #param {string} s
* #returns {boolean}
*/
function isAlphaNumericString(s) {
for (let i = 0; i < s.length; i++) {
if (!isAlphaNumeric(s[i])) {
return false;
}
}
return true;
}
const isAlphaNumeric = (str) => {
let n1 = false,
n2 = false;
const myBigBrainString =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const myHackyNumbers = "0123456789";
for (let i = 0; i < str.length; i++) {
if (myBigBrainString.indexOf(str.charAt(i)) >= 0) {
n1 = true;
}
if (myHackyNumbers.indexOf(str.charAt(i)) >= 0) {
n2 = true;
}
if (n1 && n2) {
return true;
}
}
return n1 && n2;
};
Works till eternity..
Removed NOT operation in alpha-numeric validation. Moved variables to block level scope. Some comments here and there. Derived from the best Micheal
function isAlphaNumeric ( str ) {
/* Iterating character by character to get ASCII code for each character */
for ( let i = 0, len = str.length, code = 0; i < len; ++i ) {
/* Collecting charCode from i index value in a string */
code = str.charCodeAt( i );
/* Validating charCode falls into anyone category */
if (
( code > 47 && code < 58) // numeric (0-9)
|| ( code > 64 && code < 91) // upper alpha (A-Z)
|| ( code > 96 && code < 123 ) // lower alpha (a-z)
) {
continue;
}
/* If nothing satisfies then returning false */
return false
}
/* After validating all the characters and we returning success message*/
return true;
};
console.log(isAlphaNumeric("oye"));
console.log(isAlphaNumeric("oye123"));
console.log(isAlphaNumeric("oye%123"));
(/[^0-9a-zA-Z]/.test( "abcdeFGh123456" ));
Convert string to alphanumeric (Usefull in case of files names)
function stringToAlphanumeric(str = ``) {
return str
.split('')
.map((e) => (/^[a-z0-9]+$/i.test(e) ? e : '_'))
.join('')
}
const fileName = stringToAlphanumeric(`correct-('"é'è-///*$##~~*\\\"filename`)
console.log(fileName)
// expected output "correct_filename"

non-recursive JavaScript JSON parser

I have a very large JSON string that I need to parse with in-browser JavaScript. Right now, in a few browsers, I run out of stack space. Unfortunately, my JSON can contain user strings, so I can't use eval or otherwise let the browser parse it.
I've looked at a few of the standard JavaScript JSON parsers, and they are recursive. Wondering if anyone knows of any JSON parser that is safe and non-recursive. I'd be willing for it to have fewer features -- I just have a giant array of objects.
Alternatively, if someone knows of one that might be easy to modify, that would be a big help too.
EDIT: On closer inspection the stack overflow is thrown by eval() used inside the parser. So, it must be recursive.
If eval throws stackoverflow, you can use this
http://code.google.com/p/json-sans-eval/
A JSON parser that doesn't use eval() at all.
I have written json parsers that are not recursive in several languages, but until now not in javascript. Instead of being recursive, this uses a local array named stack. In actionscript this was substantially faster and more memory efficient than recursion, and I assume javascript would be similar.
This implementation uses eval only for quoted strings with backslash escapes, as both an optimization and simplification. That could easily be replaced with the string handling from any other parser. The escape handling code is long and not related to recursion.
This implementation is not strict in (at least) the following ways. It treats 8 bit characters as whitespace. It allows leading "+" and "0" in numbers. It allows trailing "," in arrays and objects. It ignores input after the first result. So "[+09,]2" returns [9] and ignores "2".
function parseJSON( inJSON ) {
var result;
var parent;
var string;
var depth = 0;
var stack = new Array();
var state = 0;
var began , place = 0 , limit = inJSON.length;
var letter;
while ( place < limit ) {
letter = inJSON.charCodeAt( place++ );
if ( letter <= 0x20 || letter >= 0x7F ) { // whitespace or control
} else if ( letter === 0x22 ) { // " string
var slash = 0;
var plain = true;
began = place - 1;
while ( place < limit ) {
letter = inJSON.charCodeAt( place++ );
if ( slash !== 0 ) {
slash = 0;
} else if ( letter === 0x5C ) { // \ escape
slash = 1;
plain = false;
} else if ( letter === 0x22 ) { // " string
if ( plain ) {
result = inJSON.substring( began + 1 , place - 1 );
} else {
string = inJSON.substring( began , place );
result = eval( string ); // eval to unescape
}
break;
}
}
} else if ( letter === 0x7B ) { // { object
stack[depth++] = state;
stack[depth++] = parent;
parent = new Object();
result = undefined;
state = letter;
} else if ( letter === 0x7D ) { // } object
if ( state === 0x3A ) {
parent[stack[--depth]] = result;
state = stack[--depth];
}
if ( state === 0x7B ) {
result = parent;
parent = stack[--depth];
state = stack[--depth];
} else {
// error got } expected state {
result = undefined;
break;
}
} else if ( letter === 0x5B ) { // [ array
stack[depth++] = state;
stack[depth++] = parent;
parent = new Array();
result = undefined;
state = letter;
} else if ( letter === 0x5D ) { // ] array
if ( state === 0x5B ) {
if ( undefined !== result ) parent.push( result );
result = parent;
parent = stack[--depth];
state = stack[--depth];
} else {
// error got ] expected state [
result = undefined;
break;
}
} else if ( letter === 0x2C ) { // , delimiter
if ( undefined === result ) {
// error got , expected previous value
break;
} else if ( state === 0x3A ) {
parent[stack[--depth]] = result;
state = stack[--depth];
result = undefined;
} else if ( state === 0x5B ) {
parent.push( result );
result = undefined;
} else {
// error got , expected state [ or :
result = undefined;
break;
}
} else if ( letter === 0x3A ) { // : assignment
if ( state === 0x7B ) {
// could verify result is string
stack[depth++] = state;
stack[depth++] = result;
state = letter;
result = undefined;
} else {
// error got : expected state {
result = undefined;
break;
}
} else {
if ( ( letter >= 0x30 && letter <= 0x39 ) || letter === 0x2B || letter === 0x2D || letter === 0x2E ) {
var exponent = -2;
var real = ( letter === 0x2E );
var digits = ( letter >= 0x30 && letter <= 0x39 ) ? 1 : 0;
began = place - 1;
while ( place < limit ) {
letter = inJSON.charCodeAt( place++ );
if ( letter >= 0x30 && letter <= 0x39 ) { // digit
digits += 1;
} else if ( letter === 0x2E ) { // .
if ( real ) break;
else real = true;
} else if ( letter === 0x45 || letter === 0x65 ) { // e E
if ( exponent > began || 0 === digits ) break;
else exponent = place - 1;
real = true;
} else if ( letter === 0x2B || letter === 0x2D ) { // + -
if ( place != exponent + 2 ) break;
} else {
break;
}
}
place -= 1;
string = inJSON.substring( began , place );
if ( 0 === digits ) break; // error expected digits
if ( real ) result = parseFloat( string );
else result = parseInt( string , 10 );
} else if ( letter === 0x6E && 'ull' === inJSON.substr( place , 3 ) ) {
result = null;
place += 3;
} else if ( letter === 0x74 && 'rue' === inJSON.substr( place , 3 ) ) {
result = true;
place += 3;
} else if ( letter === 0x66 && 'alse' === inJSON.substr( place , 4 ) ) {
result = false;
place += 4;
} else {
// error unrecognized literal
result = undefined;
break;
}
}
if ( 0 === depth ) break;
}
return result;
}
I recommend you to divide JSON string in chunks, and bring them on demand. May be using AJAX too, you can have a recipe that just fit your needs.
Using a "divide and conquer" mechanism, I think you can still use common JSON parsing methods.
Hope that helps,
JSON parsing in browser is usually done with just eval, but preceding the eval with a regular expression "lint", that is supposed to make it safe to evaluate the JSON.
There is an example on this on wikipedia:
http://en.wikipedia.org/wiki/JSON#Security_issues

Categories

Resources