regex to disallow ._ or .- (email validation / javascript) - javascript

Here's my current regex:
^([-a-zA-Z0-9'_+\/]+([-.'_+\/][-a-zA-Z0-9'_+\/]+)*)#(([a-zA-Z0-9]+((\.|[-]{1,2})[a-zA-Z0-9]+)*)\.[a-zA-Z]{2,6})$
to validate an email address (and yes I know I shouldn't try and validate email addresses except on the simplest of terms, however our email vendor will reject special characters, etc. ).
This regex satisfies all of the requirements except one -
"No hypen or underscore directly after a period"
Regex is not my specialty, although I was able to get here. Any help would be appreciated.
Thanks.

Your regex (besides of grouping (...) starts with ^[-a-zA-Z0-9'_+\/]+, which means the beginning ^ is followed with one or more + allowed characters [...]. In this case they are hyphen, lowercase/uppercase letters, numbers, apostrophe, underscore, plus or foreslash.
Second part is what you need to change. In you regex it is ([-.'_+\/][-a-zA-Z0-9'_+\/]+)*, which is a pattern that may occur multiple times, but also does not have to *. The pattern has two parts: one of allowed characters: hyphen, period/dot, apostrophe, underscore, plus or foreslash; followed by one or more of hyphen, lowercase/uppercase letters, numbers, apostrophe, underscore, plus or foreslash.
If you remove period/dot from that first part of pattern, then this character will not be allowed. But because you want period/dot to be allowed, but not with same character sets, alternative pattern has to be defined.
If this second part will be changed from your ([-.'_+\/][-a-zA-Z0-9'_+\/]+)* to pattern that has an alternative for period/dot: ([-'_+\/][-a-zA-Z0-9'_+\/]+|\.[a-zA-Z0-9'+\/]+)*, then the final regex will do what you need. As you can see, |\.[a-zA-Z0-9'+\/]+ has been added, which reads: or | pattern single period/dot followed by one or more of lowercase/uppercase letters, numbers, apostrophe, plus or foreslash.
The final regex then is:
^([-a-zA-Z0-9'_+\/]+([-'_+\/][-a-zA-Z0-9'_+\/]+|\.[a-zA-Z0-9'+\/]+)*)#(([a-zA-Z0-9]+((\.|[-]{1,2})[a-zA-Z0-9]+)*)\.[a-zA-Z]{2,6})$

Related

Difficult regular expression for name validation

I'm trying to write a regular expression to check whether or not a proposed name is valid in a gaming platform.
Rules:
Name must contain at least 3 and no more than 20 letters
Name must start with a uppercaseletter
Name must never have two uppercase letters in a row
Spaces are allowed, but must be preceded by a letter and be followed by an uppercase letter
Hyphens are allowed, but must be preceded by a letter and be followed by a lowercase letter
All uppercase letters must be followed by a lowercase letter unless they are followed by a space or hyphen
I know I can check separately for the length of the string so the first rule is irrelevant, but I figured I'd list it for good measure.
Test cases (Pass):
Foo
Hello World
Hello-world
Bigsby Platt-slatt
Test cases (Fail):
foo
Hello world
Hello-World
33333333333
What regular expression can I use to solve this? Is it reasonable to expect to do this using only regular expressions, or will the pattern need to be analyzed using a different method?
Thanks
This is a possible regular expression:
(?!.*[A-Z]{2})(?!.*[^A-Za-z][ -])(?!.* ([^A-Z]|$))(?!.*-([^a-z]|$))^[A-Z].{2,19}$
See demo on regex101.com.
Explanation:
Several of the rules can be expressed as "cannot contain" kind of rules, and they are easy to implement with negative look-ahead ((?! ... )):
No two capitals in sequence:
(?!.*[A-Z]{2})
No non-letter followed by either a space or hyphen:
(?!.*[^A-Za-z][ -])
No space that is followed by a non-capital or end of string ($):
(?!.* ([^A-Z]|$)
No hyphen followed by a non-lowercase or end of string:
(?!.*-([^a-z]|$))
Finally, the actual match is done with this: a capital followed by 2 - 19 characters:
^[A-Z].{2,19}$

regular expression for series of text

I have Googled for RegExp of organization name, but I have not found any results.
The following are the conditions:
It should not accept only special or only numeric characters.
It should be like this: letters + special characters if any (optional) + numeric (optional).
I have written the following regular expression:
if (!/^(([a-zA-Z]+)+([!#_-]*)+([\s]?)+([a-zA-Z]*))$/.test(document.signup_form.field_67.value.trim())) {
alert("Organization name should have only Alphanumeric & Special characters");
document.signup_form.field_67.focus();
return false;
}
The above is not working with the organization name "I-Tech software pvt ltd". Please suggest a better regular expression.
That's because I-Tech software pvt ltd does not match your regex. There are symbols in between spaces in I-Tech software pvt ltd, but the regex doesn't allow that.
Solution that I think you are looking for might be something like this:
/^([a-zA-Z][-\w!#\s]*)$/
I haven't tested this, but I hope you get the idea.
You can use lookahead assertions to act as conditions in the string you're trying to match:
/^(?=(?:\w*)[A-Za-z]+)(?=(?:\w*)[!#_-]+)(?=(?:\w*)\d*).+$/
(?=(?:\w*)[A-Za-z]+) is the first lookahead, requiring that the match should contain at least one letter, in other words, like you state "to not accept only special or only numeric characters."
(?=(?:\w*)[!#_-]+) is the second lookahead, stating that there should be 0 or more special characters. I don't think this is necessary to match, because in the previous lookahead, it requires at least one letter.
(?=(?:\w*)\d*) is the third lookahead, stating that there should be zero or more digits. Again, probably not necessary, but to illustrate your requirement in your question.
Finally, the string to actually match is .+, meaning there must be at least one character present in the field you're testing. The ^ and $ characters denote to check the whole string. Hope that helps.

JavaScript regular expressions to match no digits, whitespace and selected symbols

Thanks for taking a look.
My goal is to come up with a regexp that will match input that contains no digits, whitespace or the symbols !#£$%^&*()+= or any other symbol I may choose.
I am however struggling to grasp precisely how regular expressions work.
I started out with the simple pattern /\D/, which from my understanding will match the first non-digit character it can find. This would match the string 'James' which is correct but also 'James1' which I don't want.
So, my understanding is that if I want to ensure that a pattern is not found anywhere in a given string, I use the ^ and $ characters, as in /^\D$/. Now because this will only match a single character that is not a digit, I needed to use + to specify that 1 or more digits should not be founds in the entire string, giving me the expression /^\D+$/. Brilliant, it no longer matches 'James1'.
Question 1
Is my reasoning up to this point correct?
The next requirement was to ensure no whitespace is in the given string. \s will match a single whitespace and [^\s] will match the first non-whitespace character. So, from my understanding I just had to add this to what I have already to match strings that contain no digits and no whitespace. Again, because [^\s] will only match a single non-white space character, I used + to match one or more whitespace characters, giving the new regexp of /^\D+[^\s]+$/.
This is where I got lost, as the expression now matches 'James1' or even 'James Smith25'. What? Massively confused at this point.
Question 2
Why is /^\D+[^\s]+$/ matching strings that contain spaces?
Question 3
How would I go about writing the regular expression I'm trying to solve?
While I am keen to solve the problem I am more interested in figuring where my understanding of regular expressions is lacking, so any explanations would be helpful.
Not quite; ^ and $ are actually "anchors" - they mean "start" and "end", it's actually a little more complicated, but you can consider them to mean the start and end of a line for now - look up the various modifiers on regular expressions if you're interested in learning more about this. Unfortunately ^ has an overloaded meaning; if used inside square brackets it means "not", which is the meaning you are already acquainted with. It's very important that you understand the difference between these two meanings and that the definition in your head actually applies only to character range matching!
Contributing further to your confusion is that \d means "a numerical digit" and \D means "not a numerical digit". Similarly \s means "a whitespace (space/tab/newline/etc.) character" and \S means "not a whitespace character."
It's worth noting that \d is effectively a shortcut for [0-9] (note that - has a special meaning inside square brackets), and \D is a shortcut for [^0-9].
The reason it's matching strings that contain spaces is that you've asked for "1+ non-numerical digits followed by 1+ non-space characters" - so it'll match lots of strings! I think that perhaps you don't understand that regular expressions match bits of strings, you're not adding constraints as you go, but rather building up bots of matchers that will match bits of corresponding strings.
/^[^\d\s!#£$%^&*()+=]+$/ is the answer you're looking for - I'd look at it like this:
i. [] - match a range of characters
ii. []+ - match one or more of that range of characters
iii. [^\d\s]+ - match one or more characters that do not match \d (numerical digit) or \s (whitespace)
iv. [^\d\s!#£$%^&*()+=]+ - here's a bunch of other characters I don't want you to match
v. ^[^\d\s!#£$%^&*()+=]+$ - now there are anchors applied, so this matcher has to apply to the whole line otherwise it fails to match
A useful website to explore regexs is http://regexr.com/3b9h7 - which I supply with my suggested solution as an example. Edit: Pruthvi Raj's link to debuggerx is awesome!
Is my reasoning up to this point correct?
Almost. /\D/ matches any character other than a digit, but not just the first one (if you use g option).
and [^\s] will match the first non-whitespace character
Almost, [^\s] will match any non-whitespace character, not just the first one (if you use g option).
/^\D+[^\s]+$/ matching strings that contain spaces?
Yes, it does, because \D matches a space (space is not a digit).
Why is /^\D+[^\s]+$/ matching strings that contain spaces?
Because \D+ in /^\D+[^\s]+$/can match spaces.
Conclusion:
Use
^[^\d\s!#£$%^&*()+=]+$
It will match strings that have no digits and spaces, and the symbols you do not allow.
Mind that to match a literal -, ] or [ with a character class, you either need to escape them, or use at the start or end of the expression. To play it safe, escape them.
Just insert every character you don't want to include in a negated character class as follows:
^[^\s\d!#£$%^&*()+=]*$
DEMO
Debuggex Demo
^ - start of the string
[^...] - matches one character that is not in `...`
\s - matches a whitespace (space, newline,tab)
\d - matches a digit from 0 to 9
* - a quantifier that repeats immediately preceeding element by 0 or more times
so the regex matches any string that has
1. string that has a beginning
2. containing 0 or more number of characters that is not whitesapce, digit, and all the symbols included in the character class ( In this example !#£$%^&*()+=) i.e., characters that are not included in the character class `[...]`
3.that has ending
NOTE:
If the symbols you don't want it to have also includes - , a hyphen, don't put it in between some other characters because it is a metacharacter in character class, put it at last of character class

need a regex for password validation that allows all special characters [duplicate]

This question already has an answer here:
Password validation (regex?)
(1 answer)
Closed 8 years ago.
The password requirements are:
at least two letters
at least two numbers
at least one special character (any special character)
at least 8 characters
This one is close but isn't working:
/^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W]).{8,}$/
What am I doing wrong?
This regex meets your requirements:
/^(?=(?:[^a-z]*[a-z]){2})(?=(?:[^0-9]*[0-9]){2})(?=.*[!-\/:-#\[-`{-~]).{8,}$/i
Play with the demo to see what matches and doesn't match.
Explanation
This is a classic password validation technique with lookarounds as explained in this article
The i flag at the end makes it case-insensitive so we don't have to say a-zA-Z
The ^ anchor asserts that we are at the beginning of the string
The first lookahead (?=(?:[^a-z]*[a-z]){2}) asserts that what follows at this position (the beginning of the string) is any characters that are not a letter, followed by one letter... twice, ensuring there are at least two letters
The second lookahead (?=(?:[^0-9]*[0-9]){2}) asserts that what follows at this position (still the beginning of the string) is any characters that are not a digit, followed by one digit... twice, ensuring there are at least two letters
The third lookahead (?=.*[!-\/:-#\[-{-~])` asserts that what follows at this position (still the beginning of the string) is any characters, followed by one special character
The $ anchor asserts that we are at the end of the string
Note about special characters
The regex [!-\/:-#\[-{-~]` specifically picks out all printable chars that are neither digits nor letters from the ASCII table. If this includes chars you don't want, make it more restrictive.
A regex is probably inappropriate for this; it's hard to glance at the regex you've got and immediately have any idea what the requirements are, let alone how to modify them. You might want to just count the number of characters in each group directly, then check that those counts all pass the appropriate threshold.
That said: consider that this would enforce really awkward passwords, yet disallow xkcd-style passwords. I strongly encourage you to take a more heuristic approach, where a longer password loosens the other restrictions. There are other considerations to enforcing a strong password, too, like similarity to dictionary words and number of unique characters.
Honestly you might be best off just requiring passphrases :)
I'd say:
/^(?=.*\d.*\d)(?=.*[a-zA-Z].*[a-zA-Z])(?=.*[\W]).{8,}$/
Your regex was missing the 2 digits and 2 letters requirements.
How about:
/^(?=.{2,}\d)(?=.{2,}[a-zA-Z])(?=.*[\W]).{8,}$/
It should meet your requirement.
Depends on what you consider to be a "special character". If a special character is anything that is not a digit or a letter, and if Spaces are not allowed in the password, then:
^(?=(?:\S*\d){2})(?=(?:\S*[A-Za-z]){2})(?=\S*[^A-Za-z0-9])\S{8,}
or, with the "escapes":
"^(?=(?:\\S*\\d){2})(?=(?:\\S*[A-Za-z]){2})(?=\\S*[^A-Za-z0-9])\\S{8,}"
If you choose to allow spaces, replace \S with a dot .
If you want to define "special characters" as only including certain characters, or as excluding other characters in addition to letters and digits, edit the character class in the final lookahead.

Email verification regex failing on hyphens

I'm attempting to verify email addresses using this regex: ^.*(?=.{8,})[\w.]+#[\w.]+[.][a-zA-Z0-9]+$
It's accepting emails like a-bc#def.com but rejecting emails like abc#de-f.com (I'm using the tool at http://tools.netshiftmedia.com/regexlibrary/ for testing).
Can anybody explain why?
Here is the explaination:
In your regualr expression, the part matches a-bc#def.com and abc#de-f.com is [\w.]+[.][a-zA-Z0-9]+$
It means:
There should be one or more digits, word characters (letters, digits, and underscores), and whitespace (spaces, tabs, and line breaks) or '.'. See the reference of '\w'
It is followed by a '.',
Then it is followed one or more characters within the collection a-zA-Z0-9.
So the - in de-f.com doesn't matches the first [\w.]+ format in rule 1.
The modified solution
You could adjust this part to [\w.-]+[.][a-zA-Z0-9]+$. to make - validate in the #string.
Because after the # you're looking for letters, numbers, _, or ., then a period, then alphanumeric. You don't allow for a - anywhere after the #.
You'd need to add the - to one of the character classes (except for the single literal period one, which I would have written \.) to allow hyphens.
\w is letters, numbers, and underscores.
A . inside a character class, indicated by [], is just a period, not any character.
In your first expression, you don't limit to \w, you use .*, which is 0+ occurrences of any character (which may not actually be what you want).
Use this Regex:
var email-regex = /^[^#]+#[^#]+\.[^#\.]{2,}$/;
It will accept a-bc#def.com as well as emails like abc#de-f.com.
You may also refer to a similar question on SO:
Why won't this accept email addresses with a hyphen after the #?
Hope this helps.
Instead you can use a regex like this to allow any email address.
^[a-zA-Z][\w\.-]*[a-zA-Z0-9]#[a-zA-Z][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$
Following regex works:
([A-Za-z0-9]+[-.-_])*[A-Za-z0-9]+#[-A-Za-z0-9-]+(\.[-A-Z|a-z]{2,})+

Categories