Home > Software engineering >  How do i allow only one (dash or dot or underscore) in a user form input using regular expression in
How do i allow only one (dash or dot or underscore) in a user form input using regular expression in

Time:08-22

I'm trying to implement a username form validation in javascript where the username

  • can't start with numbers
  • can't have whitespaces
  • can't have any symbols but only One dot or One underscore or One dash

example of a valid username: the_user-one.123
example of invalid username: 1----- user

i've been trying to implement this for awhile but i couldn't figure out how to have only one of each allowed symbol:-

const usernameValidation = /(?=^[\w.-] $)^\D/g 
console.log(usernameValidation.test('1username')) //false
console.log(usernameValidation.test('username-One')) //true

CodePudding user response:

Preface: Due to my severe carelessness, I assumed the context was usage of the HTML pattern attribute instead of JavaScript input validation. I leave this answer here for posterity in case anyone really wants to do this with regex.


Although regex does have functionality to represent a pattern occuring consecutively within a certain number of times (via {<lower-bound>,<upper-bound>}), I'm not aware of regex having "elegant" functionality to enforce a set of patterns each occuring within a range of number of times but in any order and with other patterns possibly in between.

Some workarounds I can think of:

Make a regex that allows for one of each permutation of ordering of special characters (note: newlines added for readability):

^(?:
(?:(?:(?:[A-Za-z][A-Za-z0-9]*\.?)|\.)[A-Za-z0-9]*-?[A-Za-z0-9]*_?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*\.?)|\.)[A-Za-z0-9]*_?[A-Za-z0-9]*-?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*-?)|-)[A-Za-z0-9]*\.?[A-Za-z0-9]*_?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*-?)|-)[A-Za-z0-9]*_?[A-Za-z0-9]*\.?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*_?)|_)[A-Za-z0-9]*\.?[A-Za-z0-9]*-?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*_?)|_)[A-Za-z0-9]*-?[A-Za-z0-9]*\.?)
)[A-Za-z0-9]*$

Note that the above regex can be simplified if you don't want usernames to start with special characters either.

Friendly reminder to also make sure you use the HTML attributes to enforce a minimum and maximum input character length where appropriate.

If you feel that regex isn't well suited to your use-case, know that you can do custom validation logic using javascript, which gives you much more control and can be much more readable compared to regex, but may require more lines of code to implement. Seeing the regex above, I would personally seriously consider the custom javascript route.

Note: I find https://regex101.com/ very helpful in learning, writing, and testing regex. Make sure to set the "flavour" to "JavaScript" in your case.

CodePudding user response:

["valid-usrId1","1nvalidUsrId","inva-lid.userId","An0therVal1d-One"].forEach(u=>console.log(u,chck(u)));

function chck(s){
  return !!s.match(/^[a-zA-Z][a-zA-Z0-9._-]*$/) && ( s.match(/[._-]/g) || []).length<2
}

  • Related