Home > Back-end >  Regular expression with a conditional statement that validates a phone number in JavaScript
Regular expression with a conditional statement that validates a phone number in JavaScript

Time:03-03

Although I have used regular expressions fairly often, I rarely create my own. I've been reading up on them recently as I need to create some fairly specific expressions for a project I am working on.

I have a very specific brief as to which telephone numbers are allowed in a form. There are restrictions on either the first two or else the first three numbers.

Numbers must start with 06 or 07, or alternatively with 081, 082, 083 or 084.

I have written a regular expression with a conditional statement that I believe should do one of two things:

  1. If the number starts with 06 or 07, then check that the other 8 characters in the string are numbers.
  2. If the number starts with 08, check that the next character is between 1 and 4, then check that the other 7 characters are numbers.

I used this tutorial to learn how conditionals work in regex. Here is the expression that I created:

const validMobile = new RegExp(/^((0)?([6-7])[0-9]{8}|([8])[1-4][0-9]{7}) *$/);

What I understand here is as follows:

  • /^ (Starts with)
  • (0) (must have a zero first)
  • ?([6*7]) (if the second character is six or seven)
  • [0-9]{8} (check that the next eight characters are numbers between zero and 9)
  • |(8) (else if the second character is eight)
  • [1-4] (check that the third character is a number between one and four)
  • [0-9]{7} (check that the following seven characters are numbers between zero and nine)

Note that the length of the string is being checked elsewhere, although I think this expression should also facilitate a check that the number is exactly 10 characters long.

This is not delivering the expected result, so I must be misunderstanding something. Could anyone please help me understand where I might be going wrong?

CodePudding user response:

  • The round brackets are not for fun: if you don't want to capture anything then don't use them. Use them only for your (this|that) problem, where the pipe works as an OR operator.
  • The square brackets don't need ranges if all you allow are 2 characters.
  • If one character is mandatory then just write it. Don't put it in square brackets, and don't put it in round brackets.
  • ? is a quantifier, meaning what came before is optional (can occur 0 times or once). If you put that behind your zero then you make it the opposite of "must be in there".

With that knowledge in mind and writing the regex onto multiple lines and ignoring any whitespaces inbetween it then comes to:

^0(
   [67][0-9]{8}
  |
   8[1-4][0-9]{7}
  )$

I also removed the optional whitespaces after your phone number: you nowhere explained that you wanted such a thing, nor was it in your list. It makes no sense either to allow spaces only after the phone number but not in front. So the * part is not for fun either.

I also strongly discourage from using regex on phone numbers: people tend to input phone numbers not without spaces or hyphens inbetween. Have a look at all the existing Qs.

CodePudding user response:

The problem with your regexp are the two alternatives (0)?([6-7])[0-9]{8} and ([8])[1-4][0-9]{7}. You have the leading zero inside the first one, so a number like 0811234567, which needs to match the second one, won't ever match. If you move the zero from the first alternative to the outside, it starts to work as you intended:

^0(([6-7])[0-9]{8}|(8)[1-4][0-9]{7}) *$

See for yourself on regex101...

Further comments on the original regexp:

  • the ? after the zero actually makes it optional, that's why I removed it.
  • you have some suspicious capturing groups (([6-7]) and ([8])), do you really need those?
  • more cleanup as motivated by @AmigoJack: character class [8] without effect -> 8.
  • Related