繁体   English   中英

在 Javascript 中重新格式化美国电话号码的正则表达式

[英]Regular Expression to reformat a US phone number in Javascript

我正在寻找重新格式化(替换,而不是验证 - 有许多用于验证的参考)电话号码以显示在 Javascript 中。 以下是一些数据的示例:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (空白/空)
  • 1234567890

有没有一种简单的方法可以使用正则表达式来做到这一点? 我正在寻找最好的方法来做到这一点。 有没有更好的办法?

我想将号码重新格式化为以下格式: (123) 456-7890

假设您想要格式“ (123) 456-7890 ”:

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '');
  var match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
  if (match) {
    return '(' + match[1] + ') ' + match[2] + '-' + match[3];
  }
  return null;
}

这是一个允许可选的+1国际代码的版本:

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '');
  var match = cleaned.match(/^(1|)?(\d{3})(\d{3})(\d{4})$/);
  if (match) {
    var intlCode = (match[1] ? '+1 ' : '');
    return [intlCode, '(', match[2], ') ', match[3], '-', match[4]].join('');
  }
  return null;
}
formatPhoneNumber('+12345678900') // => "+1 (234) 567-8900"
formatPhoneNumber('2345678900')   // => "(234) 567-8900"

可能的解决方案:

function normalize(phone) {
    //normalize string and remove all unnecessary characters
    phone = phone.replace(/[^\d]/g, "");

    //check if number length equals to 10
    if (phone.length == 10) {
        //reformat and return phone number
        return phone.replace(/(\d{3})(\d{3})(\d{4})/, "($1) $2-$3");
    }

    return null;
}

var phone = '(123)4567890';
phone = normalize(phone); //(123) 456-7890

 var x = '301.474.4062'; x = x.replace(/\\D+/g, '') .replace(/(\\d{3})(\\d{3})(\\d{4})/, '($1) $2-$3'); alert(x);

这个答案借用了 maerics 的答案。 它的主要区别在于它接受部分输入的电话号码并格式化已输入的部分。

phone = value.replace(/\D/g, '');
const match = phone.match(/^(\d{1,3})(\d{0,3})(\d{0,4})$/);
if (match) {
  phone = `${match[1]}${match[2] ? ' ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}`;
}
return phone

我正在使用此函数来格式化美国数字。

function formatUsPhone(phone) {

    var phoneTest = new RegExp(/^((\+1)|1)? ?\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})( ?(ext\.? ?|x)(\d*))?$/);

    phone = phone.trim();
    var results = phoneTest.exec(phone);
    if (results !== null && results.length > 8) {

        return "(" + results[3] + ") " + results[4] + "-" + results[5] + (typeof results[8] !== "undefined" ? " x" + results[8] : "");

    }
    else {
         return phone;
    }
}

它接受几乎所有可以想象的写美国电话号码的方式。 结果被格式化为 (987) 654-3210 x123 的标准格式

倒退思考

仅取最后一位数字(最多 10 位)而忽略第一个“1”。

function formatUSNumber(entry = '') {
  const match = entry
    .replace(/\D+/g, '').replace(/^1/, '')
    .match(/([^\d]*\d[^\d]*){1,10}$/)[0]
  const part1 = match.length > 2 ? `(${match.substring(0,3)})` : match
  const part2 = match.length > 3 ? ` ${match.substring(3, 6)}` : ''
  const part3 = match.length > 6 ? `-${match.substring(6, 10)}` : ''    
  return `${part1}${part2}${part3}`
}

键入时的示例输入/输出

formatUSNumber('+1333')
// (333)

formatUSNumber('333')
// (333)

formatUSNumber('333444')
// (333) 444

formatUSNumber('3334445555')
// (333) 444-5555

我已经扩展了David Baucum 的答案,以支持最多 4 位数字的扩展。 它还包括原始问题中要求的括号。 当您在字段中键入时,此格式将起作用。

phone = phone.replace(/\D/g, '');
const match = phone.match(/^(\d{1,3})(\d{0,3})(\d{0,4})(\d{0,4})$/);
if (match) {
    phone = `(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}${match[4] ? ' x' : ''}${match[4]}`;
}
return phone;

这是一个同时接受电话号码和带分机号码的电话号码。

function phoneNumber(tel) {
var toString = String(tel),
    phoneNumber = toString.replace(/[^0-9]/g, ""),
    countArrayStr = phoneNumber.split(""),
    numberVar = countArrayStr.length,
    closeStr = countArrayStr.join("");
if (numberVar == 10) {
    var phone = closeStr.replace(/(\d{3})(\d{3})(\d{4})/, "$1.$2.$3"); // Change number symbols here for numbers 10 digits in length. Just change the periods to what ever is needed.
} else if (numberVar > 10) {
    var howMany = closeStr.length,
        subtract = (10 - howMany),
        phoneBeginning = closeStr.slice(0, subtract),
        phoneExtention = closeStr.slice(subtract),
        disX = "x", // Change the extension symbol here
        phoneBeginningReplace = phoneBeginning.replace(/(\d{3})(\d{3})(\d{4})/, "$1.$2.$3"), // Change number symbols here for numbers greater than 10 digits in length. Just change the periods and to what ever is needed. 
        array = [phoneBeginningReplace, disX, phoneExtention],
        afterarray = array.splice(1, 0, " "),
        phone = array.join("");

} else {
    var phone = "invalid number US number";
}
return phone;
}

phoneNumber("1234567891"); // Your phone number here

当用户尝试在分隔符上退格时,尤其是从字符串的中间退格时,几乎所有这些都会出现问题。

这是一个处理该问题的 jquery 解决方案,并确保在您编辑时光标停留在正确的位置:

//format text input as phone number (nnn) nnn-nnnn
$('.myPhoneField').on('input', function (e){
    var $phoneField = e.target;
    var cursorPosition = $phoneField.selectionStart;
    var numericString = $phoneField.value.replace(/\D/g, '').substring(0, 10);

    // let user backspace over the '-'
    if (cursorPosition === 9 && numericString.length > 6) return;

    // let user backspace over the ') '
    if (cursorPosition === 5 && numericString.length > 3) return;
    if (cursorPosition === 4 && numericString.length > 3) return;

    var match = numericString.match(/^(\d{1,3})(\d{0,3})(\d{0,4})$/);
    if (match) {
        var newVal = '(' + match[1];
        newVal += match[2] ? ') ' + match[2] : '';
        newVal += match[3] ? '-' + match[3] : '';

        // to help us put the cursor back in the right place
        var delta = newVal.length - Math.min($phoneField.value.length, 14);      
        $phoneField.value = newVal;
        $phoneField.selectionEnd = cursorPosition + delta;
    } else {
        $phoneField.value = '';        
    }
})

2021年

libphonenumber-js

例子

import parsePhoneNumber from 'libphonenumber-js'

const phoneNumber = parsePhoneNumber('+12133734253')

phoneNumber.formatInternational() === '+1 213 373 4253'
phoneNumber.formatNational() === '(213) 373-4253'
phoneNumber.getURI() === 'tel:+12133734253'
var numbers = "(123) 456-7890".replace(/[^\d]/g, ""); //This strips all characters that aren't digits
if (numbers.length != 10) //wrong format
    //handle error
var phone = "(" + numbers.substr(0, 3) + ") " + numbers.substr(3, 3) + "-" + numbers.substr(6); //Create format with substrings

您可以使用此功能来检查有效的电话号码并将其标准化:

let formatPhone = (dirtyNumber) => {
 return dirtyNumber.replace(/\D+/g, '').replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}

let isPhone = (phone) => {
   //normalize string and remove all unnecessary characters
   phone = phone.replace(/\D+/g, '');
   return phone.length == 10? true : false;
}

上述解决方案是优越的,特别是如果使用 Java,并且遇到更多的超过 10 位数字的号码,例如国际代码前缀或附加分机号码。 这个解决方案是基本的(我是正则表达式世界的初学者)并且在设计时考虑到了美国电话号码,并且仅适用于只有 10 个数字且可能带有一些格式字符,或者可能根本没有格式字符(只有 10 个数字)的字符串)。 因此,我只建议将此解决方案用于半自动应用程序。 我个人更喜欢将数字存储为不带格式字符的 10 个数字,但也希望能够将电话号码转换或清理为标准格式,普通人和应用程序/手机可以随意立即识别。

我遇到了这篇文章,寻找可以与具有 PCRE 正则表达式功能(但没有 Java 功能)的文本清理器应用程序一起使用的内容。 我将在此处为那些可以使用简单的纯正则表达式解决方案的人发布这篇文章,该解决方案可以在各种文本编辑器、清理器、扩展器甚至一些剪贴板管理器中工作。 我个人使用 Sublime 和 TextSoap。 此解决方案是为 Text Soap 制作的,因为它位于菜单栏中,并提供了一个下拉菜单,您可以在其中触发对光标选择的内容或剪贴板中的内容的文本操作操作。

我的方法本质上是两个替换/搜索和替换正则表达式。 每次替换搜索和替换都涉及两个正则表达式,一个用于搜索,一个用于替换。

替换/搜索和替换 #1

  • 第一次替换/搜索和替换将非数字数字从其他 10 位数字剥离为 10 位字符串。

第一个替换/搜索正则表达式: \\D

  • 此搜索字符串匹配所有数字字符。

第一次替换/替换正则表达式:“”(什么都没有,甚至没有空格)

  • 将替换字段完全留空,不应存在包括空格在内的空白区域。 这将导致所有匹配的非数字字符被删除。 您应该在此操作之前输入 10 位数字 + 格式字符,然后输出 10 位数字 sans 格式字符。

替换/搜索和替换 #2

  • 操作的第二个替换/搜索和替换搜索部分捕获区号$1的组,第二组三个数字$2的捕获组,以及最后一组四个数字$3的最后一个捕获组。 操作替代部分的正则表达式在捕获的数字组之间插入美国电话号码格式。

第二次替换/搜索正则表达式: (\\d{3})(\\d{3})(\\d{4})

第二次替换/替换正则表达式: \\($1\\) $2\\-$3

  • 反斜杠\\转义特殊字符( , ) (<-whitespace) 和-因为我们将它们插入到捕获组$1$2$3捕获的号码之间, $2用于美国电话号码格式化。

  • 在 TextSoap 中,我创建了一个自定义清理器,其中包含两个替换操作操作,因此在实践中感觉与执行脚本相同。 我确信这个解决方案可以改进,但我预计复杂性会增加很多。 如果有人想添加此解决方案,欢迎将此解决方案的改进版本作为学习经验。

基于 David Baucum 的回答——这里有一个版本,它试图在 React onChange 事件处理程序中“在你输入时”改进自动替换:

function formatPhoneNumber(phoneNumber) {
  const cleanNum = phoneNumber.toString().replace(/\D/g, '');
  const match = cleanNum.match(/^(\d{3})(\d{0,3})(\d{0,4})$/);
  if (match) {
    return '(' + match[1] + ') ' + (match[2] ? match[2] + "-" : "") + match[3];
  }
  return cleanNum;
}

//...

onChange={e => setPhoneNum(formatPhoneNumber(e.target.value))}

只要有 3 个数字,它就会插入 (###) 然后它会继续跟随 RegEx 直到它看起来像这样 (###) ###-####

对于美国电话号码

/^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/

让我们把这个正则表达式分成更小的片段,以便于理解。

  • /^\\(? : 表示电话号码可能以可选的( .
  • (\\d{3}) : 可选后(必须有 3 个数字。如果电话号码没有( ,则必须以 3 个数字开头。例如(308308 .
  • \\)? : 表示电话号码的前 3 位数字后可以有一个可选的)
  • [- ]? :接下来的电话号码可以具有可选连字号( -之后) ,如果存在或后前3位数字。
  • (\\d{3}) :那么必须还有 3 个数字。 例如(308)-135308-135308135
  • [- ]? :在第二组 3 位数字之后,电话号码可以有另一个可选的连字符 ( - )。 例如(308)-135-308-135-308135-
  • (\\d{4})$/ :最后,电话号码必须以四位数字结尾。 例如(308)-135-7895308-135-7895308135-78953081357895

    参考 :

http://www.zparacha.com/phone_number_regex/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM