Reputation: 412
So, I suck terribly at regex and javascript. As such, when I realized I needed to validate a form field via jquery to ensure that at least one alpha character was used, I decided to ask you fine folks for some help.
I want to allow user to use apostrophes, spaces, dashes, periods, underscores, and alphanumeric chars in this field. They must, however, use at least one alpha character.
Here is the validator method I created, which does everything but ensure that at least one alpha char is used.
$.validator.addMethod("nameRegex", function(value, element) {
return this.optional(element) || /[^a-z/g]+/gi.test(value) || !/[^\.\'\:\-_ a-z0-9]+/gi.test(value);
}, "Name must contain at least one letter.");
Any tips/hints/insights/insults? Thanks everyone!
Upvotes: 0
Views: 1421
Reputation: 10665
I have had luck doing a look ahead for the required letter then matching only on valid characters for the minimum length. In my example I use a minimum length of 8 characters with valid characters of apostrophe, space, hyphen, period, underscore, and alphanumeric characters. The '\w' character class is suppose to match underscore and alphanumerics I believe. It seems to work in my tests:
var r = new RegExp("^(?=([` -.]|\\w)*?[a-zA-Z])([` -.]|\\w){8,}$")
> r.test('12345678') //all numbers shouldn't work
false
> r.test('12345678a') //long enough and one letter should work
true
> r.test('12345`_bc') //allow ` _
true
> r.test('a12345`_') //shouldn't matter if letter is in front
true
> r.test('123a45`_') //shouldn't matter if letter is in middle
true
> r.test('12345`_29') //even if special characters no letter should not work
false
EDIT: I added a '?' after the '*' in the look ahead to make the quantifier non-greedy. Also I should note that I tested this in Chrome and obviously my test cases are not conclusive. I hope this helps though. Another approach is to match zero to many valid characters, at least 1 letter, then zero to many valid characters. Something like:
var r = new RegExp("^([` -.]|\\w)*[a-zA-Z]+([` -.]|\\w)*$")
Upvotes: 1