JavaScript regex valid name - javascript

I want to make a JavaScript regular expression that checks for valid names.
minimum 2 chars (space can't count)
space en some special chars allowed (éàëä...)
I know how to write some seperatly but not combined.
If I use /^([A-Za-z éàë]{2,40})$/, the user could input 2 spaces as a name
If I use /^([A-Za-z]{2,40}[ éàë]{0,40})$/, the user must use 2 letters first and after using space or special char, can't use letters again.
Searched around a bit, but hard to formulate search string for my problem. Any ideas?

Please, please pretty please, don't do this. You will only end up upsetting people by telling them their name is not valid. Several examples of surnames that would be rejected by your scheme: O'Neill, Sørensen, Юдович, 李. Trying to cover all these cases and more is doomed to failure.
Just do something like this:
strip leading and trailing blanks
collapse consecutive blanks into one space
check if the result is not empty
In JavaScript, that would look like:
name = name.replace(/^\s+/, "").replace(/\s+$/, "").replace(/\s+/, " ");
if (name == "") {
// show error
} else {
// valid: maybe put trimmed name back into form
}

Most solutions don't consider the many different names there might be. There can be names with only two character like Al or Bo or someone that writes his name like F. Middlename Lastname.
This RegExp will validate most names but you can optimize it to whatever you want:
/^[a-z\u00C0-\u02AB'´`]+\.?\s([a-z\u00C0-\u02AB'´`]+\.?\s?)+$/i
This will allow:
Li Huang Wu
Cevahir Özgür
Yiğit Aydın
Finlay Þunor Boivin
Josué Mikko Norris
Tatiana Zlata Zdravkov
Ariadna Eliisabet O'Taidhg
sergej lisette rijnders
BRIANA NORMINA HAUPT
BihOtZ AmON PavLOv
Eoghan Murdo Stanek
Filimena J. Van Der Veen
D. Blair Wallace
But will not allow:
Shirley24
66Bryant Hunt88
http://stackoverflow.com
laoise_ibtihaj
hippolyte#example.com
Cy4n 4ur0r4 Blyth3 3ll1
Justisne
Danny
If the name needs to be capitalized, uppercase, lowercase, trimmed or single spaced, that's a task a formatter should do, not the user.

I would like to propose a RegEx that would match all latin based languages with their special characters:
/\A([ áàíóúéëöüñÄĞİŞȘØøğışÐÝÞðýþA-Za-z-']*)\z/
P.S. I've included all characters I could find, but please feel free to edit the answer in case I've missed any.

Why not
var reg= /^([A-Za-z]{2}[ éàëA-Za-z]*)$/;
2 letters, then as many spaces, letters or special characters as you want.
I wouldn't allow spaces in usernames though - it's begging for trouble when you have usernames like
ab ba
who's going to remember how many spaces they used?

You could do this:
/^([A-Za-zéàë]{2,40} ?)+$/
2-40 characters, and then optionally a space, repeated at least once. This will allow a space at the end, but you could trim it off separately.

After 'trim' the input value, The following will math your request only for Latin surnames.
rn = new RegExp("([\w\u00C0-\u02AB']+ ?)+","gi");
m = ln.match(rn);
valid = (m && m.length)? true: false;
Note that I am using '+', instead of '{2,}', that is because some surnames uses just one letter in a separated word like "Ortega y Gasset"
You can see I am not using RegExp.test, this is because that method don't work properly (I don't know why, but it has a high fail-rate, you may see it here:.
In my country, people from non-latin-language countries usually do some translation of their names so the previous RegExp would be enough. However, if you attempt to match any surname in the world, you may add more range of \u#### characters, avoiding to include symbols, numbers or other type. Or perhaps the xregexp library may help you.
And, please, do not forget to test the input in server side, and escaping it before using it in the sql sentences (if you have them)

Related

Regex in Google Apps Script practical issue. Forms doesn't read regex as it should

I hope its just something i'm not doing right.
I've been using a simple script to create a form out of a spreadsheet. The script seems to be working fine. The output form is going to get some inputs from third parties so i can analyze them in my consulting activity.
Creating the form was not a big deal, the structure is good to go. However, after having the form creator script working, i've started working on its validations, and that's where i'm stuck at.
For text validations, i will need to use specific Regexes. Many of the inputs my clients need to give me are going to be places' and/or people's names, therefore, i should only allow them usign A-Z, single spaces, apostrophes and dashes.
My resulting regexes are:
//Regex allowing a **single name** with the first letter capitalized and the occasional use of "apostrophes" or "dashes".
const reg1stName = /^[A-Z]([a-z\'\-])+/
//Should allow (a single name/surname) like Paul, D'urso, Mac'arthur, Saint-Germaine ecc.
//Regex allowing **composite names and places names** with the first letter capitalized and the occasional use of "apostrophes" or "dashes". It must avoid double spaces, however.
const regNamesPlaces = /^[^\s]([A-Z]|[a-z]|\b[\'\- ])+[^\s]$/
//This should allow (names/surnames/places' names) like Giulius Ceasar, Joanne D'arc, Cosimo de'Medici, Cosimo de Medici, Jean-jacques Rousseau, Firenze, Friuli Venezia-giulia, L'aquila ecc.
Further in the script, these Regexes are called as validation pattern for the forms text items, in accordance with each each case.
//Validation for single names
var val1stName = FormApp.createTextValidation()
.setHelpText("Only the person First Name Here! Use only (A-Z), a single apostrophe (') or a single dash (-).")
.requireTextMatchesPattern(reg1stName)
.build();
//Validation for composite names and places names
var valNamesPlaces = FormApp.createTextValidation()
.setHelpText(("Careful with double spaces, ok? Use only (A-Z), a single apostrophe (') or a single dash (-)."))
.requireTextMatchesPattern(regNamesPlaces)
.build();
Further yet, i have a "for" loop that creates the form based on the spreadsheets fields. Up to this point, things are working just fine.
for(var i=0;i<numberRows;i++){
var questionType = data[i][0];
if (questionType==''){
continue;
}
else if(questionType=='TEXTNamesPlaces'){
form.addTextItem()
.setTitle(data[i][1])
.setHelpText(data[i][2])
.setValidation(valNamesPlaces)
.setRequired(false);
}
else if(questionType=='TEXT1stName'){
form.addTextItem()
.setTitle(data[i][1])
.setHelpText(data[i][2])
.setValidation(val1stName)
.setRequired(false);
}
The problem is when i run the script and test the resulting form.
Both validations types get imported just fine (as can be seen in the form's edit mode), but when testing it in preview mode i get an error, as if the Regex wasn't matching (sry the error message is in portuguese, i forgot to translate them as i did with the code up there):
A screenshot of the form in edit mode
A screeshot of the form in preview mode
However, if i manually remove the bars out of this regex "//" it starts working!
A screenshot of the form in edit mode, Regex without bars
A screenshot of the form in preview mode, Regex without bars
What am i doing wrong? I'm no professional dev but in my understanding, it makes no sense to write a Regex without bars.
If this is some Gforms pattern of reading regexes, i still need all of this to be read by the Apps script that creates this form after all. If i even try to pass the regex without the bars there, the script will not be able to read it.
const reg1stName = ^[A-Z]([a-z\'])+
const regNamesPlaces = ^[^\s]([A-Z]|[a-z]|\b[\'\- ])+[^\s]$
//Can't even be saved. Returns: SyntaxError: Unexpected token '^' (line 29, file "Code.gs")
Passing manually all the validations is not an option. Can anybody help me?
Thanks so much
This
/^[A-Z]([a-z\'\-])+/
will not work because the parser is trying to match your / as a string literal.
This
^[A-Z]([a-z\'\-])+
also will not work, because if the name is hyphenated, you will only match up to the hyphen. This will match the 'Some-' in 'Some-Name', for example. Also, perhaps you want a name like 'Saint John' to pass also?
I recommend the following :)
^[A-Z][a-z]*[-\.' ]?[A-Z]?[a-z]*
^ anchors to the start of the string
[A-Z] matches exactly 1 capital letter
[a-z]* matches zero or more lowercase letters (this enables you to match a name like D'Urso)
[-\.' ]? matches zero or 1 instances of - (hyphen), . (period), ' (apostrophe) or a single space (the . (period) needs to be escaped with a backslash because . is special to regex)
[A-Z]? matches zero or 1 capital letter (in case there's a second capital in the name, like D'Urso, St John, Saint-Germaine)

JavasScript Regex to exclude specific characters which are stored in a string variable, spaces, and change remaining characters to underscores

This is for a hangman-type guessing game. I already figured out how to use a Regex to display the letters as underscores on the page with appropriate spacing. Now I want use a Regex to do the following, all in one expression:
Check a string containing the correct answer this.answers[arraysIndex], against the string containing all of the user's correct guesses rightString
In the correct answer string: change only the letters that don't match the correct guesses string into underscores. This means I want to keep the spaces unchanged too.
I've tried this:
var regex = new RegExp("/(?![^"+rightString+"])/[\A-Za-z/])/","g");
newDisplay = (this.answers[arraysIndex]).replace(regex, "_");
...and this:
newDisplay = (this.answers[arraysIndex]).replace("/(?![^+rightString+])/[\A-Za-z/])/g", "_")
...and countless slight variations of each. I'm not married to the idea of using a string variable, I could use an array variable too, or maybe there's something that hasn't even occurred to me. I've researched exhaustively on here and many other resources (that's how I solved my first problem) but this one's got me beat. Any help is greatly appreciated.

Phone number validation - excluding non repeating separators

I have the following regex for phone number validation
function validatePhonenumber(phoneNum) {
var regex = /^[1-9]{3}[-\s\.]{0,1}[0-9]{3}[-\s\.]{0,1}[0-9]{4}$/;
return regex.test(phoneNum);
}
However, I would liek to make sure it doesn;t pass for different separators such as in
111-222.3333
Any ideas how to make sure the separators are the same always?
Just make sure beforehand that there is at most one kind of separator, then pass the string through the regex as you were doing.
function validatePhonenumber(phoneNum) {
var separators = extractSeparators(phoneNum);
if(separators.length > 1) return false;
var regex = /^[1-9]{3}[-\s\.]{0,1}[0-9]{3}[-\s\.]{0,1}[0-9]{3}$/;
return regex.test(phoneNum);
}
function extractSeparators(str){
// Return an array with all the distinct chars
// that are present in the passed string
// and are not numeric (0-9)
}
You can use the following regex instead:
\d{3}([-\s\.])?\d{3}\1?\d{4}
Here is a working example:
http://regex101.com/r/nN9nT7/1
As result it will match the following result:
111-222-3333 --> ok
111.222.3333 --> ok
111 222 3333 --> ok
111-222.3333
111.222-3333
111-222 3333
111 222-3333
EDIT: after Alan Moore's suggestion:
Also matches 111-2223333. That's because you made the \1 optional,
which isn't necessary. One of JavaScript's stranger quirks is that a
backreference to a group that did not participate in the match,
succeeds anyway. So if there's no first separator, ([-\s.])? succeeds
because the ? made it optional, and \1 succeeds because it's
JavaScript. But I would have used ([-\s.]?) to capture the first
separator (which might be nothing), and \1 to match the same thing
again. This works in any flavor, including JavaScript.
We can improve the regex to:
^\d{3}([-\s\.]?)\d{3}\1\d{4}$
You'll need at least two passes to keep this maintainable and extensible.
JS' RegEx doesn't allow for creating variables for use later in the RegEx, if you want to support older browsers.
If you are only supporting modern browsers, Fede's answer is just fine...
As such, with ghetto-support, you aren't going to be able to reliably check that one separator is the same value every time, without writing a really, really, really, stupidly-long RegEx, using | to basically write out the RegEx 3 times.
A better way might be to grab all of the separators, and use a reduction or a filter to check that they all have the same value.
var userEnteredNumber = "999.231 3055";
var validNumber = numRegEx.test(userEnteredNumber);
var separators = userEnteredNumber.replace(/\d+/g, "").split("");
var firstSeparator = separators[0];
var uniformSeparators = separators.every(function (separator) { return separator === firstSeparator; });
if (!uniformSeparators) { /* also not valid */ }
You could make that a little neater, using closures and some applied functions, but that's the idea.
Alternatively, here's the big, ugly RegEx that would allow you to test exactly what the user entered.
var separatorTest = /^([0-9]{3}\.[0-9]{3}\.[0-9]{3,4})|([0-9]{3}-[0-9]{3}-[0-9]{3,4})|([0-9]{3} [0-9]{3} [0-9]{3,4})|([0-9]{9,10})$/;
Notice I had to include the exact same number-test three times, wrap each one in parens (to be treated as a single group), and then separate each group with an | to check each group, like an if, else if, else... ...and then plug in a separate special case for having no separator at all...
...not pretty.
I'm also not using \d, just because it's easy to forget that - and . are both accepted "digit"s, when trying to maintain one of these abominations.
Now, a word or two of warning:
People are liable to enter all kinds of crap; if this is for a commercial site, it's likely better to just strip separators entirely and validate the number is the right size, and conforms to some specifics (eg: doesn't start with /^555555/).
If not given any instruction about number format, people will happily use either no separator or a formal number, like (555) 555-5555 (or +1 (555) 555-5555 for the really pedantic), which is obviously going to fail hard, in this system (see point #1).
Be prepared to trim what you get, before validating.
Depending on your country/region/etc laws about data-security and consumer-vs-transaction record-keeping (again, may or may not be more important in a commercial setting), it's likely better to store both a "user-given" ugly number, and a system-usable number, which you either clean on the back-end, or submit along with the user-entered text.
From a user-interaction perspective, either forcing the number to conform, explicitly (placeholders showing them xxx-xxx-xxxx right above the input, in bold), or accepting any text, and prepping it yourself, is going to be 1000x better than accepting certain forms, but not bothering to tell the user up-front, and instead telling them what they did was wrong, after they try.
It's not cool for relationships; it's equally not cool, here.
You've got 9-digit and 10-digit numbers, so if you're trying for an international solution, be prepared to deal with all international separators (, \.\-\(\)\+) etc... again, why stripping is more useful, because THAT RegEx would be insane.

How to modify regex for phone numbers and accept only digits

I have this following regex method for the jquery validate plugin.
jQuery.validator.addMethod("phoneUS", function(phone_number, element) {
phone_number = phone_number.replace(/\s+/g, "");
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
}, "Please specify a valid phone number");
Currently, its validating against phone numbers in this format : 203-123-1234
I need to change to validate like this: 2031231234
Does anyone have a quick and easy solution for me?
You can replace
phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
with this
phone_number.match(/\d{10}/);
\d means match any digit
and
{10} means 10 times
Getting rid of all those -? sequences is probably the quickest way - they mean zero or one - characters.
That will reduce it to:
/^(1)?(\([2-9]\d{2}\)|[2-9]\d{2})[2-9]\d{2}\d{4}$/
whih can be further simplified to:
/^1?(\([2-9]\d{2}\)|[2-9]\d{2})[2-9]\d{6}$/
If you also want to disallow the brackets around area codes, you can further simplify it to:
/^1?[2-9]\d{2}[2-9]\d{6}$/
(and, technically, it won't match the literal 203-123-1234 since the character immediately after that first - has to be 2 thru 9, so I'm assuming you were just talking about the format rather than the values there).
I think better approach would be changing the whole expression with simpler version, something like this:
/^[0-9]{10}$/
Edited, Note (see comments):
This is just a limited example of how to validate a format: 111-222-3333 vs 1112223333, not proper US phone number validation.
If you just want ten digits, then
phone_number.match(/\d{10}/)
will do it. If you want to match any of the other conditions in there (eg match both 1-2031231234 and 2031231234), you will need to add more.
As a side note, what you currently have doesn't match 203-123-1234 because the first digit after the first hyphen is a 1, and it is looking for 2-9 in that spot.
([0-9]{10}) this will match with 10 digit number.
You can use if you want to match all formats, including 203-123-1234 and 2031231234
EDIT : I'm no regex expert, but I added "1-" support
/^(?:1-?)?[(]?\d{3}[)]?\s?-?\s?\d{3}\s?-?\s?\d{4}$/
By the way, there's a really nice AIR tool for regex, it's called RegExr and you can get the desktop version here http://www.gskinner.com/RegExr/desktop/ or use the online version http://gskinner.com/RegExr/ . There's also a "community" section that contains a lot of useful working regex. That's where I took that one.

find regex for validating terms (keyword) input

unfortunately i'm poor in regex! can you guide me to write a regex in javascript which can determine my terms input box. a user should input terms with this format:
#(all alphanumeric chars + blank + dash + quotation )
for example:
#keyword1#key word2#keyword3#key-word4#key'word5
and these inputs should be illegal:
#####
##keyword1#key2#
# #keyword
#!%^&
As you wrote a term is specified by:
/#[a-zA-Z0-9 '-]+/
Repeat that pattern, and force it to contain the start and end of the string with ^ and $.
/^(#[a-zA-Z0-9 '-]+)+$/
/#[a-zA-Z0-9][a-zA-Z0-9 '-]+/
When you said "# #keyword" should be invalid, I've assumed you mean "# " should be invalid and "#keyword" should be extracted from that string. The first 'box' means a keyword will always begin with a lowercase letter, uppercase letter, or number. If thats too restrictive and you want to allow for example "#-keyword", just add dash in before the first close-square-bracket, like so:
/#[a-zA-Z0-9-][a-zA-Z0-9 '-]+/
And to return an array of results in javascript, apply it to the string using the "global" modifier ('g' after the second slash):
arrayOfKeywords = keywordString.match(/#[a-zA-Z0-9-][a-zA-Z0-9 '-]+/g);
You may wish to see this code at my test page. Regular-expressions.info is a useful site to learn more about regular expressions. They also have an interactive page to test regexes on, which can be useful when playing around.

Categories

Resources