I'm trying to write a regex in which I want to test for 2 things. The string is only valid when it starts with +20 and its length is between 1 and 5, or when it doesn't start with +20 but it still has the plus sign + as its first character (example +50) and its length is between 1 and 7 then it's valid too.
Here is what I wrote for this validation :
/^\+(?=20){1,5}|^\+(?!20){1,7}/g
I tested it but it doesn't work how I intended for it and I dont understand why.
What you have is close, but you need to:
. to be quantified (. can work to match everything)$g flag since you only want one matchThat leaves you with:
/^\+(?=20).{1,5}$|^\+(?!20).{1,7}$/
which you can also write as
/^\+((?=20).{1,5}|(?!20).{1,7})$/
In your regular expression, (?=20){1,5} reads, "execute the positive lookahead (?=20){1,5} between 1 and 5 times". That has the same effect as executing it once, clearly not what you want. What you want for that part of the expression is
(?=20).{1,5}
which reads, "match between 1 and 5 characters, the first two of which must be '20'".
That's still a problem however, because that matches '+20012' in the string '+20012 quick brown dogs' You need an end-of-string anchor:
^\+(?=20).{1,4}$|...
Notice I also changed {1,5} to {1,4}, as the string may contain at most 5 characters, or at most 4 after '+'. Also observe that the above is the same as
^\+20.{1,2}$|...
which is simpler and arguably reads better. So you could modify your entire regular expression to be
^\+20.{1,2}$|^\+(?!20).{1,6}$/g
or, to reduce repetition,
^\+(?:20.{1,2}|(?!20).{1,6})$/g
For one, that matches '+200X'. It should, unless by,"...when it starts with +20..." you mean, "...when it starts with +20 not followed by a digit...". I have assumed you meant the latter in my solution that follows.
You could attempt to match the following regular expression:
^\+(?:20(\D.?)?|(?!20(?!\d)).{0,6})$
The expression can be broken down as follows.
^ # match beginning of string
\+ # match '+'
(?: # begin non-capture group
20 # match '20'
(?:\D.?)? # optionally match a non-digit that is optionally
# followed by any character
| # or
(?! # begin negative lookahead
20 # match '20'
(?!\d) # negative lookahead asserts '20' is not followed by a digit
) # end negative lookahead
.{0,6} # match between 0 and 6 characters
) # end non-capture group
$ # match end of string
Note that '+200' is matched by the second part of the alternation (the string does not begin with '20').