Javascriptで電話番号のバリデーションと変換(E.164)に便利なライブラリの紹介


今回したいこと

  • 日本の電話番号(03-1234-5678)などを、E.164表記(+81312345678)に変換したい
  • ついでにバリデーションも出来るといいかも

環境

  • Node.js

ライブラリ

Googleが提供している電話番号をバリデーションと自動フォーマット可能なlibphonenumberのnpm版であるgoogle-libphonenumberを使用します。

google-libphonenumberの使用方法

インストール

npm install google-libphonenumber

例1)'202-456-1414'を'US'のE164表記に変換

// Require `PhoneNumberFormat`.
const PNF = require('google-libphonenumber').PhoneNumberFormat;

// Get an instance of `PhoneNumberUtil`.
const phoneUtil = require('google-libphonenumber').PhoneNumberUtil.getInstance();

// Parse number with country code and keep raw input.
const number = phoneUtil.parseAndKeepRawInput('202-456-1414', 'US');

// Format number in the E164 format.
console.log(phoneUtil.format(number, PNF.E164));
// => +12024561414

例2)全角・半角混合の日本の電話番号をE164表記に変換

// Require `PhoneNumberFormat`.
const PNF = require('google-libphonenumber').PhoneNumberFormat;
// Get an instance of `PhoneNumberUtil`.
const phoneUtil = require('google-libphonenumber').PhoneNumberUtil.getInstance();

const phoneNumbers = [
        '03―1111―2222',
        '03 1111 2222',
        '(03)1111-2222',
        '0312345678',
        '03 1234 5678',
        '03-1234-5678',
        '(03)-1234-5678',
        '09012345678',
        '090-1234-5678',
        '09012345678',
        '090―1234―5678',
        '0120-123-123'
        ]
const replacedNumbers = phoneNumbers.map(phoneNumber => {
        const replacedNumber = formatNumber(phoneNumber);
        return replacedNumber;
    })

function formatNumber(str){
    const number = phoneUtil.parseAndKeepRawInput(str, 'JP');
    return phoneUtil.format(number, PNF.E164);
}

console.log(replacedNumbers);

// =>["+81311112222","+81311112222","+81311112222","+81312345678","+81312345678","+81312345678","+81312345678","+819012345678","+819012345678","+819012345678","+819012345678","+81120123123"]

その他の使い方

READMEをそのままのっけています。
バリデーションも出来そうです。


// Require `PhoneNumberFormat`.
const PNF = require('google-libphonenumber').PhoneNumberFormat;

// Get an instance of `PhoneNumberUtil`.
const phoneUtil = require('google-libphonenumber').PhoneNumberUtil.getInstance();

// Parse number with country code and keep raw input.
const number = phoneUtil.parseAndKeepRawInput('202-456-1414', 'US');

// Print the phone's country code.
console.log(number.getCountryCode());
// => 1

// Print the phone's national number.
console.log(number.getNationalNumber());
// => 2024561414

// Print the phone's extension.
console.log(number.getExtension());
// =>

// Print the phone's extension when compared to i18n.phonenumbers.CountryCodeSource.
console.log(number.getCountryCodeSource());
// => FROM_DEFAULT_COUNTRY

// Print the phone's italian leading zero.
console.log(number.getItalianLeadingZero());
// => false

// Print the phone's raw input.
console.log(number.getRawInput());
// => 202-456-1414

// Result from isPossibleNumber().
console.log(phoneUtil.isPossibleNumber(number));
// => true

// Result from isValidNumber().
console.log(phoneUtil.isValidNumber(number));
// => true

// Result from isValidNumberForRegion().
console.log(phoneUtil.isValidNumberForRegion(number, 'US'));
// => true

// Result from getRegionCodeForNumber().
console.log(phoneUtil.getRegionCodeForNumber(number));
// => US

// Result from getNumberType() when compared to i18n.phonenumbers.PhoneNumberType.
console.log(phoneUtil.getNumberType(number));
// => FIXED_LINE_OR_MOBILE

// Format number in the E164 format.
console.log(phoneUtil.format(number, PNF.E164));
// => +12024561414

// Format number in the original format.
console.log(phoneUtil.formatInOriginalFormat(number, 'US'));
// => (202) 456-1414

// Format number in the national format.
console.log(phoneUtil.format(number, PNF.NATIONAL));
// => (202) 456-1414

// Format number in the international format.
console.log(phoneUtil.format(number, PNF.INTERNATIONAL));
// => +1 202-456-1414

// Format number in the out-of-country format from US.
console.log(phoneUtil.formatOutOfCountryCallingNumber(number, 'US'));
// => 1 (202) 456-1414

// Format number in the out-of-country format from CH.
console.log(phoneUtil.formatOutOfCountryCallingNumber(number, 'CH'));
// => 00 1 202-456-1414

(おまけ)ライブラリを使わないでやってみた

最初はgoogle-libphonenumberを知らなかったので、正規表現でやってみました。


const phoneNumbers = [
        '03―1111―2222',
        '03 1111 2222',
        '(03)1111-2222',
        '0312345678',
        '03 1234 5678',
        '03-1234-5678',
        '(03)-1234-5678',
        '09012345678',
        '090-1234-5678',
        '09012345678',
        '090―1234―5678',
        '0120-123-123'
        ]

const replacedNumbers = phoneNumbers.map(phoneNumber => {
        const replacedNumber = toE164Number(phoneNumber);
        return replacedNumber;
    })


function toE164Number(strVal){
  // 半角変換
  const halfVal = strVal.replace(/[!-~]/g,
    function( tmpStr ) {
      // 文字コードをシフト
      return String.fromCharCode( tmpStr.charCodeAt(0) - 0xFEE0 );
    }
  );
  console.log("halfVal" ,halfVal);
  // 文字の変換
  const number = phoneUtil.parseAndKeepRawInput(halfVal, 'JP');
  console.log(number)
  console.log(phoneUtil.format(number, PNF.E164));
  return halfVal.replace(/[\-\s+()-―]/gi, '').replace('0','+81');
}

最後に

google-libphonenumberはかなり便利だなと思いました。
ただ電話番号を変換するときにJPなどの国コードを指定しないといけないので、素の電話番号形式から国コードを判定するものがあればいいんですけどね。。