Regex match valid Phone Number - javascript

I'm quite new to regex, and not sure what I'm doing wrong exactly.
I'm looking for a regex that match the following number format:
Matching requirements:
Must start with either 0 or 3
Must be between 7 to 11 digits
Must not allow ascending digits. e.g. 0123456789, 01234567
Must not allow repeated digits. e.g. 011111111, 3333333333, 0000000000
This is what I came up with:
^(?=(^[0,3]{1}))(?!.*(\d)\1{3,})(?!^(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$).{7,11}$
The above regex fails the No. (4) condition. Not sure why though.
Any help would be appreciated.
Thanks

A few notes about the pattern that you tried
You can omit the {1} and the comma in [0,3]
In the lookahead (?!.*(\d)\1{3,}) the (\d) is the second capturing group because this (?=(^[0,3]{1})) contains the first capturing group so it should be \2 instead of \1
In the lookahead, you can omit the comma in {3,}
In the match itself you use .{7,11} where the dot would match any character except a newline. You could use \d instead to match only digits
You pattern might look like
^(?=(^[03]))(?!.*(\d)\2{3})(?!^(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$)\d{7,11}$
Regex demo
Or leaving out the first lookahead and move that to the match, changing the quantifier to \d{6,10} and repeating capture group \1 instead of \2
^(?!.*(\d)\1{3})(?!(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$)[03]\d{6,10}$
Regex demo
Edit
Based on the comments, the string not having 4 ascending digits:
^(?!.*(\d)\1{3})[03](?!\d*(?:0123|1234|2345|3456|4567|5678|6789))\d{6,10}$
Regex demo

A solution for a JS flavor of PCRE would be
/^[03](?!123456(7(8(9|$)|$)|$))(?!(?<d>.)\k<d>+$)[0-9]{6,10}$/
Explanations
^[03] starts at the beginning of the string, then reads either 0 or 3
(?!123456(7(8(9|$)|$)|$)) makes sure that, after this first char, there is no sequence (if a sequence can be read, then the negative lookahead fails
(?!(?<d>.)\k<d>+$) is another negative lookahead : it ensures that the first char read (flagged d) is not repeated again and again until end of string
[0-9]{6,10}$/ finally reads 6 to 10 digits (first one already read)
A few tests:
"0123456789: No match"
"01234567: No match"
"01234568: No match"
"011111111: No match"
"33333333: No match"
"333333233 is valid"
"042157891023 is valid"
"019856: No match"
"0123451245 is valid"

Related

Limit 10 characters is numbers and only 1 dot

I'm having a regex problem when input
That's the requirement: limit 10 characters (numbers) including dots, and only 1 dot is allowed
My current code is only 10 characters before and after the dot.
^[0-9]{1,10}\.?[0-9]{0,10}$
thank for support.
You could assert 10 chars in the string being either . or a digit.
Then you can match optional digits, and optionally match a dot and again optional digits:
^(?=[.\d]{10}$)\d*(?:\.\d*)?$
The pattern matches:
^ Start of string
(?=[.\d]{10}$) Positive lookahead, assert 10 chars . or digit till the end of string
\d* Match optional digits
(?:\.\d*)? Optionally match a `. and optional digits
$ End of string
See a regex demo.
If the pattern should not end on a dot:
^(?=[.\d]{10}$)\d*(?:\.\d+)?$
Regex demo
The decimal point throws a wrench into most single pattern approaches. I would probably use an alternation here:
^(?:\d{1,10}|(?=\d*\.)(?!\d*\.\d*\.)[0-9.]{2,11})$
This pattern says to match:
^ from the start of the number
(?:
\d{1,10} a pure 1 to 10 digit integer
| OR
(?=\d*\.) assert that one dot is present
(?!\d*\.\d*\.) assert that ONLY one dot is present
[0-9.]{2,11} match a 1 to 10 digit float
)
$ end of the number
You can use a lookahead to achieve your goals.
First, looking at your regex, you've used [0-9] to represent all digit characters. We can shorten this to \d, which means the same thing.
Then, we can focus on the requirement that there be only one dot. We can test for this with the following pattern:
^\d*\.?\d*$
\d* means any number of digit characters
\.? matches one literal dot, optionally
\d* matches any number of digit characters after the dot
$ anchors this to the end of the string, so the match can't just end before the second dot, it actually has to fail if there's a second dot
Now, we don't actually want to consume all the characters involved in this match, because then we wouldn't be able to ensure that there are <=10 characters. Here's where the lookahead comes in: We can use the lookahead to ensure that our pattern above matches, but not actually perform the match. This way we verify that there is only one dot, but we haven't actually consumed any of the input characters yet. A lookahead would look like this:
^(?=\d*\.?\d*$)
Next, we can ensure that there are aren't more than 10 characters total. Since we already made sure there are only dots and digits with the above pattern, we can just match up to 10 of any characters for simplicity, like so:
^.{1,10}$
Putting these two patterns together, we get this:
^(?=\d*\.?\d*$).{1,10}$
This will only match number inputs which have 10 or fewer characters and have no more than one dot.
If you would like to ensure that, when there is a dot, there is also a digit accompanying it, we can achieve this by adding another lookahead. The only case that meets this condition is when the input string is just a dot (.), so we can just explicitly rule this case out with a negative lookahead like so:
(?!\.$)
Adding this back in to our main expression, we get:
^(?=\d*\.?\d*$)(?!\.$).{1,10}$

Using lookahead, how to ensure at least 4 alphanumeric chars are included + underscores

I'm trying to make sure that at least 4 alphanumeric characters are included in the input, and that underscores are also allowed.
The regular-expressions tutorial is a bit over my head because it talks about assertions and success/failure if there is a match.
^\w*(?=[a-zA-Z0-9]{4})$
my understanding:
\w --> alphanumeric + underscore
* --> matches the previous token between zero and unlimited times ( so, this means it can be any character that is alphanumeric/underscore, correct?)
(?=[a-zA-Z0-9]{4}) --> looks ahead of the previous characters, and if they include at least 4 alphanumeric characters, then I'm good.
Obviously I'm wrong on this, because regex101 is showing me no matches.
You want 4 or more alphanumeric characters, surround by any number of underscores (use ^ and $ to ensure it match's the whole input ):
^(_*[a-zA-Z0-9]_*){4,}$
Your pattern ^\w*(?=[a-zA-Z0-9]{4})$ does not match because:
^\w* Matches optional word characters from the start of the string, and if there are only word chars it will match until the end of the string
(?=[a-zA-Z0-9]{4}) The positive lookahead is true, if it can assert 4 consecutive alphanumeric chars to the right from the current position. The \w* allows backtracking, and can backtrack 4 positions so that the assertion it true.
But the $ asserts the end of the string, which it can not match as the position moved 4 steps to the left to fulfill the previous positive lookahead assertion.
Using the lookahead, what you can do is assert 4 alphanumeric chars preceded by optional underscores.
If the assertion is true, match 1 or more word characters.
^(?=(?:_*[a-zA-Z0-9]){4})\w+$
The pattern matches:
^ Start of string
(?= Positive lookahead, asser what is to the right is
(?:_*[a-zA-Z0-9]){4} Repeat 4 times matching optional _ followed by an alphanumeric char
) Close the lookahead
\w+ Match 1+ word characters (which includes the _)
$ End of string
Regex demo
I suggest using atomic groups (?>...), please see regex tutorial for details
^(?>_*[a-zA-Z0-9]_*){4,}$
to ensure 4 or more fragments each of them containing letter or digit.
Edit: If regex doesn't support atomic, let's try use just groups:
^(?:_*[A-Za-z0-9]_*){4,}$

Regular Expressions: Positive and Negative Lookahead Solution

I was doing Freecodecamp RegEx challange, which's about:
Use lookaheads in the pwRegex to match passwords that are greater than 5 characters long, do not begin with numbers, and have two consecutive digits
So far the solution I found passed all the tests was:
/^[a-z](?=\w{5,})(?=.*\d{2}\.)/i
However, when I tried
/^[a-z](?=\w{5,})(?=\D*\d{2,}\D*)/i
I failed the test trying to match astr1on11aut (but passed with astr11on1aut). So can someone help me explaining how ?=\D*\d{2,}\D* failed this test?
So can someone help me explaining how (?=\D*\d{2,}\D*) failed this
test?
Using \D matches any char except a digit, so from the start of the string you can not pass single digit to get to the 2 digits.
Explanation
astr1on11aut astr11on1aut
^ ^^
Can not pass 1 before reaching 11 Can match 2 digits first
Note
the expression could be shortened to (?=\D*\d{2}) as it does not matter if there are 2, 3 or more because 2 is the minimum and the \D* after is is optional.
the first expression ^[a-z](?=\w{5,})(?=.*\d{2}\.) can not match the example data because it expects to match a . literally after 2 digits.
Failed for the \d{2,}
Then let's have a look at the regexp match process
/^[a-z](?=\w{5,})
means start with [a-z], the length is at least 6, no problem.
(?=\D*\d{2,}\D*)
means the first letter should be followed by these parts:
[0 or more no-digit][2 or more digits][0 or more no-digits]
and lets have a look at the test case
astr1on11aut
// ^[a-z] match "a"
// length matchs
// [0 or more no-digit]: "str"
// d{2,} failed: only 1 digit
the ?= position lookahead means exact followed by.
The first regular expression is wrong, it should be
/^[a-z](?=\w{5,})(?=.*\d{2}.*)/i
When it comes to lookahead usage in regex, rememeber to anchor them all at the start of the pattern. See Lookarounds (Usually) Want to be Anchored. This will help you avoid a lot of issues when dealing with password regexps.
Now, let's see what requirements you have:
"are greater than 5 characters long" => (?=.{6}) (it requires any 6 chars other than lien break chars immediately to the right of the current location)
"do not begin with numbers" => (?!\d) (no digit allowed immediately to the right)
have two consecutive digits => (?=.*\d{2}) (any two digit chunk of text is required after any 0 or more chars other than line break chars as many as possible, immediately to the right of the current location).
So, what you may use is
^(?!\d)(?=.{6})(?=.*\d{2})
Note the most expensive part is placed at the end of the pattern so that it could fail quicker if the input is non-matching.
See the regex demo.

Regex for a string which do not start with a number and allow only alphanumeric

I am trying to create a javascript regex for below conditions
Allow Alphanumeric only
But also allow underscore(_)
Don't allow to start with a number
Don't allow to start with an underscore
I have created a regex ^(?![0-9]|[_].*$).* which will work for last two conditions above. Please suggest how can I add an and condition to make it work for all above scenarios.
You may use the following regex:
^[A-Za-z]\w*$
Details
^ - start of string
[A-Za-z] - any ASCII letter
\w* - zero or more letters/digits/_
$ - end of string.
To allow an empty string match, wrap the whole pattern with an optional non-capturing group:
^(?:[A-Za-z]\w*)?$
^^^ ^^
You can use this regex:
^(?![0-9_])\w+$
RegEx Demo
(?![0-9_]) is negative lookahead to fail the match when we have a digit or _ at the start.
you can use the regex
^[a-zA-Z][A-Za-z0-9_]*$
see the regex101 demo
You may be thinking too literally about the last two requirements. If it's alphanumeric (so.. a-z and 0-9, right?) then saying "dont allow numbers or underscore at the start" is probably the same as "must start with a letter"
^[a-z][a-z0-9_]*$
This is "must start with a-z", followed by "must follow with zero or more letters, numbers or underscores. The ^ outside of a character class (for example [a-z] is a character class) means "start of input". The $ means end of input.
If you interpreted the last two requirements literally, you could write:
[^0-9_]
This means "any character that is not 0-9 and also not an underscore" but it doesn't necessarily restrict the user from entering something other than a-z as the first character, so they might enter a #, and it would pass..

Javascript RegExp non sequential characters

I have this rule
var reg = new RegExp('[a-z]{3}');
Which means it is allowed to use characters between a-z and at least 3 occurrences.
So, I am wondering if there is a way to match this rule with non sequential characters.
In other words,
"abc" => valid
"aaa" => not valid
Thank you!
Here is a working regex for exactly 3 (or N) characters, if the number is not fixed it gets more complicated:
^([a-z])(?!\1{2})[a-z]{2}$
1 2 3 4 5 6 7 8
Explanation:
^ matches the beginning of the string
([a-z]) match one of the accepted characters and save it (group 1)
(?!...) negative lookahead, what is in those brackets is not accepted
\1 reference to the first group (first character here)
{2} repeated exactly twice
[a-z] the accepted characters
{2} repeated exactly twice
$ matches the end of the string
Link here (I added the gm modifiers, so that several expressions can be tested.)
Try to use the excluding lookahead (?![a-z]{3}), it will not match 3 equal characters in sequence.

Categories

Resources