用 Javascript 重新格式化 US 电话号码的正则表达式

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

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

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

我想重新格式化的数字如下: (123) 456-7890

215514 次浏览

美国电话号码

/^\(?(\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-
  • 最后,电话号码必须以四位数字结尾。例如 (308)-135-7895308-135-7895308135-78953081357895

    参考文献:

Http://www.zparacha.com/phone_number_regex/

假设你想要格式“ (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"

var x = '301.474.4062';
    

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


alert(x);

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

可能的解决办法:

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

我使用这个函数来格式化美国数字。

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-3210x123的标准格式

这里是一个将接受电话号码和电话号码与分机。

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

这个答案借用了梅里克的答案。它的主要不同之处在于,它接受部分输入的电话号码,并对已输入的部分进行格式化。

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

你可以使用这个函数来检查有效的电话号码并将它们标准化:

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

回想过去

只取最后一位数字(最多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;

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

下面是一个 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 = '';
}
})

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

我偶然发现这篇文章寻找一些东西,我可以用一个文本清洁应用程序,有 PCRE 正则表达式的能力(但没有 java 函数)。我将在这里为那些可以使用一个简单的纯正则表达式解决方案的人们发布这篇文章,该解决方案可以在各种文本编辑器、清理器、扩展器甚至一些剪贴板管理器中工作。我个人用的是“崇高”和“文字肥皂”。这个解决方案是为 Text Soap 设计的,因为它位于菜单栏中,并且提供了一个下拉菜单,您可以在其中触发文本操作操作,操作对象是光标选择的内容或剪贴板中的内容。

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

替换/搜寻及更换 # 1

  • 第一个替换/搜索 & 替换将非数字数字从原来的10位数字删除为10位字符串。

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

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

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

  • 将替代字段完全保留为空白,不应存在包括空格在内的空白。这将导致删除所有匹配的非数字字符。在此操作之前,您应该使用10位数字 + 格式化字符进行操作,而不使用格式化字符得到10位数字。

替换/搜寻及替换 # 2

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

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

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

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

  • 在 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个数字,它就会插入(# # #) ,然后继续遵循正则表达式,直到它看起来像这样(# # #) # #-# # # #

二零二一年

Libphonennumber-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'

对于所有国际电话号码与国家代码高达3位,我们可以改变原来的答案一点点如下。 对于第一次匹配,我们应该寻找1-3个数字,而不是“1”。

 export const formatPhoneNumber = (phoneNumberString) => {
var cleaned = ('' + phoneNumberString).replace(/\D/g, '');
var match = cleaned.match(/^(\d{1,3}|)?(\d{3})(\d{3})(\d{4})$/);
if (match) {
var intlCode = (match[1] ? `+${match[1]} ` : '');
return [intlCode, '(', match[2], ') ', match[3], '-', match[4]].join('');
}
return null;
}
console.log( formatPhoneNumber('16464765278') )//+1 (646) 476-5278
console.log( formatPhoneNumber('+2549114765278')) //+254 (911) 476-5278
console.log( formatPhoneNumber('929876543210') )//+92 (987) 654-3210

满足我的要求。