domain name validation with custom rules - javascript

I am working on regular expression with own custom rule.
rules are the hostname must be 3-63 characters,
whole name must be 256 characters,
no special characters except dot(.), hyphen(-)
I tried this var regx = /^([A-Za-z0-9-]{3,63}?\.)+[a-zA-Z]{2,6}$/;
but the problem is the pattern is applicable to next string after dot(.). What I mean to say is
for example : "qwerty.abcde.com"
in the above "qwerty" should be 3-63 characters , but "abcde" can be any no.of characters .My pattern is applicable to next string after dot.that 3-63 rule should be applicable to only "qwerty" not to "abcde". can any one help me out.
Thanks in advance

You may use the following regex:
/^(?!.{257})[A-Za-z0-9-]{3,63}\.(?:[A-Za-z0-9-]+\.)*[a-zA-Z]{2,6}$/
See the regex demo
Details:
^ - start of string
(?!.{257}) - a negative lookahead that fails the match if the string contains 257 or more chars (other than line break chars)
[A-Za-z0-9-]{3,63} - 3 to 63 alphanumeric and - chars
\. - a dot
(?:[A-Za-z0-9-]+\.)* - zero or more sequences of
[A-Za-z0-9-]+ - 1 or more alphanumeric and - chars
\. - a dot
[a-zA-Z]{2,6} - 2 to 6 ASCII letters
$ - end of string.
So, the negative lookahead checks for the whole string length, and the {3,63} limiting quantifier is only applied to the chunk of chars before the first ..

Related

Javascript: Regex to exclude whitespace and special characters

I need a regex to validate,
Should be of length 18
First 5 characters should be either (xyz34|xyz12)
Remaining 13 characters should be alphanumeric only letters and numbers, no whitespace or special characters is allowed.
I have a pattern like here, '/^(xyz34|xyz12)((?=.*[a-zA-Z])(?=.*[0-9])){13}/g'
But this is allowing whitespace and special characters like ($,% and etc) which is violating the rule #3.
Any suggestion to exclude this whitespace and special characters and to strictly check that it must be letters and numbers?
You should not quantify lookarounds. They are non-consuming patterns, i.e. the consecutive positive lookaheads check the presence of their patterns but do not advance the regex index, they check the text at the same position. It makes no sense repeating them 13 times. ^(xyz34|xyz12)((?=.*[a-zA-Z])(?=.*[0-9])){13} is equal to ^(xyz34|xyz12)(?=.*[a-zA-Z])(?=.*[0-9]), and means the string can start with xyz34 or xyz12 and then should have at least 1 letter and at least 1 digits.
You may consider fixing the issue by using a consuming pattern like this:
If you do not care if the last 13 chars contain only digits or only letters, use the patterns suggested by other users, like /^(?:xyz34|xyz12)[a-zA-Z\d]{13}$/ or /^xyz(?:34|12)[a-zA-Z0-9]{13}$/
If there must be at least 1 digit and at least 1 letter among those 13 alphanumeric chars, use /^xyz(?:34|12)(?=[a-zA-Z]*\d)(?=\d*[a-zA-Z])[a-zA-Z\d]{13}$/.
See the regex demo #1 and the regex demo #2.
NOTE: these are regex literals, do not use them inside single- or double quotes!
Details
^ - start of string
xyz - a common prefix
(?:34|12) - a non-capturing group matching 34 or 12
(?=[a-zA-Z]*\d) - there must be at least 1 digit after any 0+ letters to the right of the current location
(?=\d*[a-zA-Z]) - there must be at least 1 letter after any 0+ digtis to the right of the current location
[a-zA-Z\d]{13} - 13 letters or digits
$ - end of string.
JS demo:
var strs = ['xyz34abcdefghijkl1','xyz341bcdefghijklm','xyz34abcdefghijklm','xyz341234567890123','xyz14a234567890123'];
var rx = /^xyz(?:34|12)(?=[a-zA-Z]*\d)(?=\d*[a-zA-Z])[a-zA-Z\d]{13}$/;
for (var s of strs) {
console.log(s, "=>", rx.test(s));
}
.* will match any string, for your requirment you can use this:
/^xyz(34|12)[a-zA-Z0-9]{13}$/g
regex fiddle
/^(xyz34|xyz12)[a-zA-Z0-9]{13}$/
This should work,
^ asserts position at the start of a line
1st Capturing Group (xyz34|xyz12)
1st Alternative xyz34 matches the characters xyz34 literally (case sensitive)
2nd Alternative xyz12 matches the characters xyz12 literally (case sensitive)
Match a single character present in the list below [a-zA-Z0-9]{13}
{13} Quantifier — Matches exactly 13 times

How to write regex to match password with rules

I'm trying to write regex to match password with following rule
Minimum length - 8 characters, if it includes a number and a lowercase letter OR 15 characters with any combination of characters
Here's my regex
^(?=.*\d[a-z]).{8,}|([a-zA-Z0-9]{15,})$
Expected result:
2232ddds - correct
ddds2222 - correct
Actual result:
2232ddds - correct
ddds2222 - incorrect
Could you help me to find a problem?
The problems are two:
The anchors only affect the alternatives they stand next to
The (?=.*\d[a-z]) lookahead requires a digit and a lowercase to appear in this order only, if there is a letter and then a digit, it won't work.
You may use
/^(?:(?=.*\d)(?=.*[a-z]).{8,}|[a-zA-Z0-9]{15,})$/
^^^|-----------------| ^ ^
See the regex demo.
If you want to make it more efficient and follow best practices use
/^(?:(?=\D*\d)(?=[^a-z]*[a-z]).{8,}|[a-zA-Z0-9]{15,})$/
Details
^ - start of string
(?: - a non-capturing group start
(?=\D*\d) - at least 1 digit
(?=[^a-z]*[a-z]) - at least 1 lowercase letter
.{8,} - any 8 or more chars other than line break chars
| - or
[a-zA-Z0-9]{15,} - 15 or more alphanumeric chars only
) - end of non-capturing group
$ - end of string.
Here a few options you can choose to build your regex:
String contains at least one:
Lower case (?=.*[a-z])
Upper case (?=.*[A-Z])
Numbers (?=.*\d)
Symbols (?=.[!##\$%\^&])
Minimal characters of string: (?=.{8,})
Your regex would be: (?=.*[a-z])(?=.*\d)(?=.{8,})|(?=.{15,})
Hope this helps!

Email validation expression allows underscore

Email validation expression /^(?!_)\w+([\.-]?\w+)*#(?!_)\w+([\.-]?\w+)*(\.\w{2,3})+$/ allows underscore for some cases, but otherwise works perfectly.
It does not fail the following email address:
tets_name#gmail.com
test____name#gmail.com
Here is the pattern :
var pattern =/^(?!_)\w+([\.-]?\w+)*#(?!_)\w+([\.-]?\w+)*(\.\w{2,3})+$/;
if (pattern.test(Email)) {
return false;
}
How can I restrict this to not allow underscore?
Note that \w matches ASCII letters ([A-Za-z]), digits ([0-9]) and an underscore.
To make sure your regex does not match underscores replace all \w with [a-zA-Z0-9] and the last \w{2,3} can be replaced with [a-zA-Z]{2,3}:
/^[a-zA-Z0-9]+(?:[.-][a-zA-Z0-9]+)*#[a-zA-Z0-9]+(?:[.-][a-zA-Z0-9]+)*\.[a-zA-Z]{2,3}$/
If you plan to match emails that only contain single underscores between letters/digits and not at the start/end use
/^[a-zA-Z0-9]+(?:[_.-][a-zA-Z0-9]+)*#[a-zA-Z0-9]+(?:[_.-][a-zA-Z0-9]+)*\.[a-zA-Z]{2,3}$/
See this regex and another regex here.
Details
^ - start of string
[a-zA-Z0-9]+ - 1 or more ASCII letters/digits
(?:[.-][a-zA-Z0-9]+)* - zero or more sequences of
[.-] - a dot or - (no need to escape a dot inside a character class)
[a-zA-Z0-9]+ - 1 or more ASCII letters/digits
# - a # char
[a-zA-Z0-9]+ - 1 or more ASCII letters/digits
(?:[.-][a-zA-Z0-9]+)* - zero or more sequences of
[.-] - a dot or - (no need to escape a dot inside a character class)
[a-zA-Z0-9]+ - 1 or more ASCII letters/digits
\. - a dot
[a-zA-Z]{2,3} - 2 or 3 ASCII letters
$ - end of string.
You may try this, i just added .* in the negative look ahead , you were only looking for single _ at the start of your string but - can be at other postitions
^(?!.*_)\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$
try demo here
see explanation on the link

Hyphen and Underscore should never be continuous but can be present in the string more than once

I have a requirement, where i have to validate a field in Excel.
Validations:
Field should start and end with [a-zA-Z0-9] but not with any special chars [-_]
It cannot contain "-" and "_" continuously more than once.
Example:
A--Badasd (Not allowed)
A__Bsdasdas (Not allowed)
A-_fdsfdsd (Not Allowed)
A_-sfsdfsdf (Not allowed)
A-B-adf (allowed)
A_b_adads (allowed)
I came up with this following regex, however, it doesn't seem to accept even the non-continuous entries of "-" and "_".
^[a-zA-z0-9]+(([\xFF01-\xFF5E]+|[\\-\\_])+)[a-zA-Z0-9]+$
[\xFF01-\xFF5E] is to not allow any double width characters, so please ignore it as it is working fine.
Any help would be greatly appreciable.
I can only suggest a lookahead based pattern (as [\xFF01-\xFF5E] matches _ and restricting it in JS regex will make the pattern more cumbersome):
/^[a-z0-9](?:(?!.*?[-_]{2})[\xFF01-\xFF5E-]*[a-z0-9])?$/i
See the regex demo.
This pattern will match strings of 1 char length, too, and will only match those strings starting and ending with an ASCII alphanumeric char and not having --, _-, -_ and __ in them.
If you want to "block" strings of length 1, i.e. set the minimum match length to 2, you should remove (?: and )? from the pattern above:
/^[a-z0-9](?!.*?[-_]{2})[\xFF01-\xFF5E-]*[a-z0-9]$/i
Details
^ - start of string
[a-z0-9] - an alphanumeric ASCII char
(?:(?!.*?[-_]{2})[\xFF01-\xFF5E_-]*[a-z0-9])? - an optional (1 or 0 occurrences) sequence of:
(?!.*?[-_]{2}) - a lookahead check that will fail the match if there are 2 consecutive - or _ anywhere after any 0+ chars other than line break chars
[\xFF01-\xFF5E-]* - any char in the \xFF01-\xFF5E range or/and -
[a-z0-9] - an alphanumeric ASCII char
$ - end of string.

Regex allowing no leading whitespace but allowing anywhere else and requiring at least one uppercase and one lowercase letters

I want regex code to validate usernames that have:
length between 6 and 30
contain at least one letter from A-Z
contain at least one digit from 0-9
not contain a space at the beginning but it might have at
the end or in the middle.
may contain special characters
So far I have tried this:
^[\S](?=.*\d)(?=.*[A-Z]).{6,30}$
It works quite good but when I choose an uppercase letter ONLY at the beginning it doesnt validate my password.
Test12 34 ----> Doesnt accept but should accept
TesT12 34 ----> Accept
tesT12 34 ----> Accept
The problem arises because the \S is at the pattern start before the lookaheads. That means, that the lookaheads that require an uppercase ASCII letter and a digit only check them after the first character in string.
Now, there can be two scenarios: 1) there may be any amount of whitespace characters in the string, but at its beginning, 2) only one whitespace char is allowed in the string, and not in the beginning
Scenario 1
Put \S after the lookaheads and decrement the limiting quantifier values to set the limits to 6-30 as \S already matches and consumes the first char:
^(?=.*\d)(?=.*[A-Z])\S.{5,29}$
^^ ^^^^
See the regex demo.
JS test:
var rx = /^(?=.*\d)(?=.*[A-Z])\S.{5,29}$/;
var vals = [ "Test12 34", "TesT12 34", "tesT12 34" ];
for (var s of vals) {
console.log(s, "=>", rx.test(s));
}
Scenario 2
Use
^(?=.{6,30}$)(?=.*\d)(?=.*[A-Z])\S+(?:\s\S*)?$
The length is restricted with the positive lookahead at the beginning ((?=.{6,30}$)) and the consuming \S+(?:\s\S*)? pattern will only allow a single \s whitespace (1 or 0 due to the last ? - one or zero occurrences quantifier) and it can be in the middle (as the first \S is quantified with +, one or more occurrences quantifier) or end (as the \S after \s is *-quantified, zero or more occurrences quantifier).
See the regex demo.

Categories