简体   繁体   English

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

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

I'm looking to reformat (replace, not validate - there are many references for validating) a phone number for display in Javascript.我正在寻找重新格式化(替换,而不是验证 - 有许多用于验证的参考)电话号码以显示在 Javascript 中。 Here's an example of some of the data:以下是一些数据的示例:

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

Is there an easy way to use a regular expression to do this?有没有一种简单的方法可以使用正则表达式来做到这一点? I'm looking for the best way to do this.我正在寻找最好的方法来做到这一点。 Is there a better way?有没有更好的办法?

I want to reformat the number to the following: (123) 456-7890我想将号码重新格式化为以下格式: (123) 456-7890

Assuming you want the format " (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;
}

Here's a version that allows the optional +1 international code:这是一个允许可选的+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"

Possible solution:可能的解决方案:

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);

This answer borrows from maerics' answer.这个答案借用了 maerics 的答案。 It differs primarily in that it accepts partially entered phone numbers and formats the parts that have been entered.它的主要区别在于它接受部分输入的电话号码并格式化已输入的部分。

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

I'm using this function to format US numbers.我正在使用此函数来格式化美国数字。

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;
    }
}

It accepts almost all imaginable ways of writing a US phone number.它接受几乎所有可以想象的写美国电话号码的方式。 The result is formatted to a standard form of (987) 654-3210 x123结果被格式化为 (987) 654-3210 x123 的标准格式

thinking backwards倒退思考

Take the last digits only (up to 10) ignoring first "1".仅取最后一位数字(最多 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}`
}

example input / output as you type键入时的示例输入/输出

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

formatUSNumber('333')
// (333)

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

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

I've extended David Baucum's answer to include support for extensions up to 4 digits in length.我已经扩展了David Baucum 的答案,以支持最多 4 位数字的扩展。 It also includes the parentheses requested in the original question.它还包括原始问题中要求的括号。 This formatting will work as you type in the field.当您在字段中键入时,此格式将起作用。

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;

Here is one that will accept both phone numbers and phone numbers with extensions.这是一个同时接受电话号码和带分机号码的电话号码。

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

Almost all of these have issues when the user tries to backspace over the delimiters, particularly from the middle of the string.当用户尝试在分隔符上退格时,尤其是从字符串的中间退格时,几乎所有这些都会出现问题。

Here's a jquery solution that handles that, and also makes sure the cursor stays in the right place as you edit:这是一个处理该问题的 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 2021年

libphonenumber-js libphonenumber-js

Example例子

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

You can use this functions to check valid phone numbers and normalize them:您可以使用此功能来检查有效的电话号码并将其标准化:

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;
}

The solutions above are superior, especially if using Java, and encountering more numbers with more than 10 digits such as the international code prefix or additional extension numbers.上述解决方案是优越的,特别是如果使用 Java,并且遇到更多的超过 10 位数字的号码,例如国际代码前缀或附加分机号码。 This solution is basic (I'm a beginner in the regex world) and designed with US Phone numbers in mind and is only useful for strings with just 10 numbers with perhaps some formatting characters, or perhaps no formatting characters at all (just 10 numbers).这个解决方案是基本的(我是正则表达式世界的初学者)并且在设计时考虑到了美国电话号码,并且仅适用于只有 10 个数字且可能带有一些格式字符,或者可能根本没有格式字符(只有 10 个数字)的字符串)。 As such I would recomend this solution only for semi-automatic applications.因此,我只建议将此解决方案用于半自动应用程序。 I Personally prefer to store numbers as just 10 numbers without formatting characters, but also want to be able to convert or clean phone numbers to the standard format normal people and apps/phones will recognize instantly at will.我个人更喜欢将数字存储为不带格式字符的 10 个数字,但也希望能够将电话号码转换或清理为标准格式,普通人和应用程序/手机可以随意立即识别。

I came across this post looking for something I could use with a text cleaner app that has PCRE Regex capabilities (but no java functions).我遇到了这篇文章,寻找可以与具有 PCRE 正则表达式功能(但没有 Java 功能)的文本清理器应用程序一起使用的内容。 I will post this here for people who could use a simple pure Regex solution that could work in a variety of text editors, cleaners, expanders, or even some clipboard managers.我将在此处为那些可以使用简单的纯正则表达式解决方案的人发布这篇文章,该解决方案可以在各种文本编辑器、清理器、扩展器甚至一些剪贴板管理器中工作。 I personally use Sublime and TextSoap.我个人使用 Sublime 和 TextSoap。 This solution was made for Text Soap as it lives in the menu bar and provides a drop-down menu where you can trigger text manipulation actions on what is selected by the cursor or what's in the clipboard.此解决方案是为 Text Soap 制作的,因为它位于菜单栏中,并提供了一个下拉菜单,您可以在其中触发对光标选择的内容或剪贴板中的内容的文本操作操作。

My approach is essentially two substitution/search and replace regexes.我的方法本质上是两个替换/搜索和替换正则表达式。 Each substitution search and replace involves two regexes, one for search and one for replace.每次替换搜索和替换都涉及两个正则表达式,一个用于搜索,一个用于替换。

Substitution/ Search & Replace #1替换/搜索和替换 #1

  • The first substitution/ search & replace strips non-numeric numbers from an otherwise 10-digit number to a 10-digit string.第一次替换/搜索和替换将非数字数字从其他 10 位数字剥离为 10 位字符串。

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

  • This search string matches all characters that is not a digit.此搜索字符串匹配所有数字字符。

First Substitution/ Replace Regex: "" (nothing, not even a space)第一次替换/替换正则表达式:“”(什么都没有,甚至没有空格)

  • Leave the substitute field completely blank, no white space should exist including spaces.将替换字段完全留空,不应存在包括空格在内的空白区域。 This will result in all matched non-digit characters being deleted.这将导致所有匹配的非数字字符被删除。 You should have gone in with 10 digits + formatting characters prior this operation and come out with 10 digits sans formatting characters.您应该在此操作之前输入 10 位数字 + 格式字符,然后输出 10 位数字 sans 格式字符。

Substitution/ Search & Replace #2替换/搜索和替换 #2

  • The second substitution/search and replace search part of the operation captures groups for area code $1 , a capture group for the second set of three numbers $2 , and the last capture group for the last set of four numbers $3 .操作的第二个替换/搜索和替换搜索部分捕获区号$1的组,第二组三个数字$2的捕获组,以及最后一组四个数字$3的最后一个捕获组。 The regex for the substitute portion of the operation inserts US phone number formatting in between the captured group of digits.操作替代部分的正则表达式在捕获的数字组之间插入美国电话号码格式。

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

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

  • The backslash \\ escapes the special characters ( , ) ,反斜杠\\转义特殊字符( , ) (<-whitespace), and - since we are inserting them between our captured numbers in capture groups $1 , $2 , & $3 for US phone number formatting purposes. (<-whitespace) 和-因为我们将它们插入到捕获组$1$2$3捕获的号码之间, $2用于美国电话号码格式化。

  • In TextSoap I created a custom cleaner that includes the two substitution operation actions, so in practice it feels identical to executing a script.在 TextSoap 中,我创建了一个自定义清理器,其中包含两个替换操作操作,因此在实践中感觉与执行脚本相同。 I'm sure this solution could be improved but I expect complexity to go up quite a bit.我确信这个解决方案可以改进,但我预计复杂性会增加很多。 An improved version of this solution is welcomed as a learning experience if anyone wants to add to this.如果有人想添加此解决方案,欢迎将此解决方案的改进版本作为学习经验。

Based on David Baucum's answer - here is a version that trys to improve auto-replacement "as you type" for example in a React onChange event handler:基于 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))}

It will insert (###) as soon as there are 3 numbers and then it will keep following the RegEx until it looks like this (###) ###-####只要有 3 个数字,它就会插入 (###) 然后它会继续跟随 RegEx 直到它看起来像这样 (###) ###-####

For US Phone Numbers对于美国电话号码

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

Let's divide this regular expression in smaller fragments to make is easy to understand.让我们把这个正则表达式分成更小的片段,以便于理解。

  • /^\\(? : Means that the phone number may begin with an optional ( . /^\\(? : 表示电话号码可能以可选的( .
  • (\\d{3}) : After the optional ( there must be 3 numeric digits. If the phone number does not have a ( , it must start with 3 digits. Eg (308 or 308 . (\\d{3}) : 可选后(必须有 3 个数字。如果电话号码没有( ,则必须以 3 个数字开头。例如(308308 .
  • \\)? : Means that the phone number can have an optional ) after first 3 digits. : 表示电话号码的前 3 位数字后可以有一个可选的)
  • [- ]? : Next the phone number can have an optional hyphen ( - ) after ) if present or after first 3 digits. :接下来的电话号码可以具有可选连字号( -之后) ,如果存在或后前3位数字。
  • (\\d{3}) : Then there must be 3 more numeric digits. (\\d{3}) :那么必须还有 3 个数字。 Eg (308)-135 or 308-135 or 308135例如(308)-135308-135308135
  • [- ]? : After the second set of 3 digits the phone number can have another optional hyphen ( - ). :在第二组 3 位数字之后,电话号码可以有另一个可选的连字符 ( - )。 Eg (308)-135- or 308-135- or 308135-例如(308)-135-308-135-308135-
  • (\\d{4})$/ : Finally, the phone number must end with four digits. (\\d{4})$/ :最后,电话号码必须以四位数字结尾。 Eg (308)-135-7895 or 308-135-7895 or 308135-7895 or 3081357895 .例如(308)-135-7895308-135-7895308135-78953081357895

    Reference :参考 :

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

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

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