74

I'm trying to validate a phone number with Yup:

phone: Yup.number()
  .typeError("That doesn't look like a phone number")
  .positive("A phone number can't start with a minus")
  .integer("A phone number can't include a decimal point")
  .min(8)
  .required('A phone number is required'),

.min(8) validates that the number is 8 or more. So simply entering 8 will pass. How can I make 8 characters required so 1000 0000 would pass?

gunr2171
  • 16,104
  • 25
  • 61
  • 88
Evanss
  • 23,390
  • 94
  • 282
  • 505

10 Answers10

142

Hi right now I'am solving same problem as you and I found possible solution.

Validate phone number with string that matches Regex

const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/

phoneNumber: Yup.string().matches(phoneRegExp, 'Phone number is not valid')

You can search for different Regex Expressions and validate it. I've used Regex from this article https://www.sitepoint.com/community/t/phone-number-regular-expression-validation/2204

filippofilip
  • 1,541
  • 1
  • 9
  • 12
  • matches(" ") is working for me, it is giving a warning as **Possible Unhandled Promise Rejection (id: 0): TypeError: Cannot read property 'length' of undefined** in react-native. Please help me – Sirisha Jan 03 '19 at 11:55
  • 1
    Sirisha I think its because your variable is not a string. Initialise your variable as empty string and then listen to onChanged event in TextInput. – filippofilip Jan 05 '19 at 16:54
  • why \\? worked for me only after removing redundant escapes. – OlehZiniak Jan 22 '20 at 11:45
  • 14
    `/^((\+[1-9]{1,4}[ -]?)|(\([0-9]{2,3}\)[ -]?)|([0-9]{2,4})[ -]?)*?[0-9]{3,4}[ -]?[0-9]{3,4}$/` worked best for me. @filippofilip your expression matches thing such as +32----------1111111 – LGenzelis Jun 25 '20 at 21:58
  • @LGenzelis I tried your regex -- but this allowed numbers with multiple + in the middle +32+232232232 – The Old County May 17 '22 at 16:23
  • https://codesandbox.io/s/regex-phone-number-validation-forked-h7bmxt?file=/src/App.js – The Old County May 18 '22 at 10:55
  • LGenzelis - https://codesandbox.io/s/regex-flipflop-phone-number-validation-forked-u124dr – The Old County May 18 '22 at 11:00
  • Flipflop -- https://codesandbox.io/s/regex-flipflop-phone-number-validation-forked-b3nh1h?file=/src/App.js – The Old County May 18 '22 at 11:00
54

>. Update .<

http://yup-phone.js.org/

I've created a yup-phone module that uses google-libphonenumber which gives accurate validation checks and can be installed directly from github

npm install --save yup yup-phone.

Check Usage

const Yup = require('yup');
require('yup-phone');

// validate any phone number (defaults to India for country)
const phoneSchema = Yup.string().phone().required();
phoneSchema.isValid('9876543210'); // → true


From Simple React Validator,

The regex for phone number validation is

/^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/

Example

// index.js

const yup = require('yup');
const { rePhoneNumber } = require('./yup-phone')

const schema = yup.string().phone()

const phone = '+911234567890';
console.log('Is Valid? ', rePhoneNumber.test(phone)); // Is Valid? true
schema.validateSync(phone);

// yup-phone.js

const yup = require('yup');

const rePhoneNumber = /^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/;

module.exports.rePhoneNumber = rePhoneNumber

yup.addMethod(yup.string, "phone", function() {
  return this.test("phone", "Phone number is not valid", value =>
    rePhoneNumber.test(value)
  );
});

abhisekp
  • 4,648
  • 2
  • 30
  • 37
  • unless I've missed something along the way, I have not been able to pass validation for a blank field. That is, I only want to validate if a value is present. – David W. Sep 18 '21 at 22:16
  • 3
    I originally gave this an upvote. However, the bundle size is larger than my entire website. Do not use it on the frontend – Will Squire Apr 04 '22 at 21:01
  • I tried to use yup-phone here -- https://codesandbox.io/s/yup-phone-validation-forked-ixgnjj -- but it will allow numbers with ++ at the front? -- "++33343335678" – The Old County May 18 '22 at 10:39
  • even google-lib phone allowed this -- https://codesandbox.io/s/google-phone-lib-demo-forked-k29kk8 "+++33343335678" – The Old County May 18 '22 at 10:41
12

Try this, it might be helpful for you.

mobile: Yup.string().matches(/^[6-9]\d{9}$/, {message: "Please enter valid number.", excludeEmptyString: false})
Aravinda Meewalaarachchi
  • 2,551
  • 1
  • 27
  • 24
Sirisha
  • 423
  • 4
  • 12
10

const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/


phone_number: Yup.string()
  .required("required")
  .matches(phoneRegExp, 'Phone number is not valid')
  .min(10, "too short")
  .max(10, "too long"),

This works best for me...you can set your own length...i just wanted 10 digits not less or more

jonschlinkert
  • 10,872
  • 4
  • 43
  • 50
Vipul Singh
  • 109
  • 1
  • 3
4

Just a little collaboration. On my case I don't want to validate if the input is empty (when is not required). Thank you all for your examples!

yup.addMethod(yup.string, "phone", function(messageError = 'Phone number is not valid') {
    const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/
    return this.test('phone', messageError, value => {
      if (value && value.length > 0) {
        return phoneRegExp.test(value)
      }
      return true
    })
})
adrxlm
  • 96
  • 2
1

I have a similar use case, and here's my solution:

// Regex source: https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s02.html

const phoneRegex = RegExp(
  /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/
);

const schema = yup.object().shape({
  phone: yup.string().matches(phoneRegex, "Invalid phone").required("Phone is required")
});
calvin
  • 31
  • 1
1

I made a new package for this called yup-phone-lite. I had used the original yup-phone package but it uses the massive google-libphonenumber so I replaced it with a smaller fork.

Chris Sandvik
  • 1,787
  • 9
  • 19
1

Here's a snippet from my code.

let schema = yup.object().shape({
  phone: yup
    .string()
    // regexr.com/6anqd
    .matches(/(\+91\ )[6-9]{1}[0-9 ]{4}[0-9 ]{4}[0-9]{3}/, {
      message: "Invalid Indian number",
      excludeEmptyString: false,
    })
    .required(),
  email: yup.string().required().email(),
  password: yup.string().required().min(8),
  confirmPassword: yup
    .string()
    .required()
    .oneOf([yup.ref("password")], "Passwords do not match"),
  agree: yup
    .boolean()
    .oneOf(
      [true],
      "It is essential to accept our Privacy Policy to register.",
    ),
});

My regex checks for Indian Phone numbers following the format, +91 axxx xxx xxx (where a can be a digit in the range 6 to 9 and x can be 0 - 9).

I tried yup-home but it was not able to actually verify the range for the Indian Number I wanted, plus, the package import size was costly.


Also, I'm using React with Formik at the frontend for form validation with react-phone-input-2

<PhoneInput
  country={"in"}
  value={values.phone}
  name="phone"
  onChange={(phone, data, e) => handleChange(e)}
  onBlur={(e) => handleBlur(e)}
  defaultMask=".... ... ..."
  masks={{ in: ".... ... ..." }}
  onlyCountries={["in"]}
  inputProps={{
    name: "phone",
    required: true,
    autoFocus: true,
  }}
  disableSearchIcon={true}
  disableDropdown={true}
  containerClass="mt-1 border h-12 text-sm focus:outline-none block w-full bg-gray-100 dark:bg-transparent border-transparent focus:bg-white"
  inputClass="mt-1 border h-12 text-sm focus:outline-none block w-full bg-gray-100 dark:bg-transparent border-transparent focus:bg-white"
  inputStyle={{
    background: "transparent",
    border: "1px solid grey",
    height: "3em",
    width: "100%",
    outline: "none",
  }}
  buttonStyle={{
    height: "3em",
    background: "transparent",
    outline: "none",
    border: "none",
  }}
/>
{handleFormikError(errors, touched, "phone")} // returns the span.alert with error message
Animesh Singh
  • 8,382
  • 1
  • 17
  • 20
0

Here is how I combined yup with other 3rd phone validation libraries ("awesome-phonenumber" in my case):

import { parsePhoneNumber } from "awesome-phonenumber";
import * as Yup from "yup";

const schema = Yup.object().shape({
  name: Yup.string().required("Required"),
  phoneNumber: Yup.string()
    .required("Required")
    .test("phoneNumber", "Phone number is not valid", (str, context) => {
      const pn = parsePhoneNumber(str);
      return pn.valid;
    }),
  addressLine1: Yup.string().required("Required"),
  // ...Other fields
});
Foxeye.Rinx
  • 420
  • 2
  • 6
0

Hi, This is regex for indian local mobile number validation and for Indian international .

starting with 9,8,7 you can add more as well.

you can test it using https://regex101.com/

import * as Yup from "yup";

const phoneNumberRules = /^(?:(?:\+|0{0,2})91(\s*[\-]\s*)?|[0]?)?[789]\d{9}$/;

const emailRules = /^[a-zA-Z0-9._%+-]+@(gmail|yahoo)\.com$/;

export const clientSchema=Yup.object().shape({

    name:Yup.string().required("Name Not be Empty"),

    email: Yup.string().email("Invalid Email!")
      .matches(emailRules, { message: " Not valid :{" })
      .required("Email Required !"),

      phone: Yup.string()
      .matches(phoneNumberRules, { message: "Invalid Phone Number!" })
      .required("Phone Number Required !"),
})
toyota Supra
  • 3,181
  • 4
  • 15
  • 19