Biểu thức chính quy để định dạng lại số điện thoại của Hoa Kỳ trong Javascript


97

Tôi đang tìm cách định dạng lại (thay thế, không xác thực - có nhiều tài liệu tham khảo để xác thực) số điện thoại để hiển thị trong Javascript. Đây là ví dụ về một số dữ liệu:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (trống / rỗng)
  • 1234567890

Có cách nào dễ dàng để sử dụng biểu thức chính quy để thực hiện việc này không? Tôi đang tìm cách tốt nhất để làm điều này. Có cách nào tốt hơn?

Tôi muốn định dạng lại số thành như sau: (123) 456-7890


3
Và cái nào trong số đó là định dạng mục tiêu của bạn?
Till Helge

Cái này: (123) 456-7890
Matt K

3
Tôi muốn nói rằng chỉ cần loại bỏ tất cả các ký tự không phải chữ số sau đó lấy ba chuỗi con.
Wiseguy

2
@Wiseguy vui lòng đăng câu trả lời đó như một câu trả lời (với một ví dụ), vì đó thực sự là những gì OP nên làm.
Brian Driscoll

1
Bạn cũng cần chỉ định cách mỗi một trong các định dạng được chấp nhận ánh xạ tới định dạng đích, điều này không rõ ràng chút nào nếu đầu vào là rỗng. Trừ khi bạn sẵn sàng sử dụng một điều kiện bổ sung để loại bỏ trường hợp đó.
Jon

Câu trả lời:


240

Giả sử bạn muốn định dạng " (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
}

Đây là phiên bản cho phép +1mã quốc tế tùy chọn :

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"

2
Hoàn hảo; cảm ơn bạn! Tuy nhiên, tôi đã thay đổi return (!m) ? nullthành return (!m) ? ""sau khi thêm chức năng này.
Matt K

2
Một bài học hay về cách tiếp cận một vấn đề. Tôi đang cố gắng nghĩ cách đối sánh tất cả các trường hợp có thể xảy ra - bạn loại bỏ những gì không liên quan và xem có phù hợp không. Rất đẹp.
Jkleg

2
FYI điều này không hoạt động đối với các số như + 1555-555-5555
Sẽ có

'' + phoneNumberStringgiống như phoneNumberString... Nó đã là một chuỗi.
YungGun

@YungGun trừ khi ai đó gọi hàm bằng một số, ví dụformatPhoneNumber(8001231234)
maerics

32

Giải pháp khả thi:

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

1
Phương pháp tuyệt vời ở đây, cảm ơn!

27

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

alert(x);


1
Cảm ơn Sean, tôi thích giải pháp nội tuyến đơn giản ngắn gọn của bạn.
user752746

1
Cám ơn vì cái này! Tôi đã đổi nó thành x = x.replace(/[^\d]+/g, '') .replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');hoạt động để thêm '+1' vào trước số điện thoại chẳng hạn
Greg A

Cảm ơn! đây chỉ là tôi cần
Albert Hidalgo

8

Câu trả lời này vay mượn từ câu trả lời của maerics. Nó khác chủ yếu ở chỗ nó chấp nhận số điện thoại được nhập một phần và định dạng các phần đã được nhập.

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ều này hoạt động khi bạn nhập, thêm ở định dạng mong muốn từ áp phích nguồn. Sau 1,5 giờ tìm kiếm, tôi rất vui vì đã thử cái này!
Mushanthrax

Tôi đã thêm dấu ngoặc đơn xung quanh mã vùng nếu điều đó hữu ích:(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}
Peter Hollingsworth

Trên thực tế, vấn đề là sau đó bạn không thể xóa lùi dấu '-' hoặc khoảng trắng từ giữa chuỗi. Bạn cần ngăn định dạng lại khi người dùng lùi khoảng cách (ví dụ: newstring.length < oldstring.lengthHOẶC để theo dõi vị trí con trỏ và tìm ra khi nào người dùng vừa đặt lại khoảng cách trên các dấu phân cách đó, ví dụif (cursorPosition === 4 && numericString.length > 3)
Peter Hollingsworth

Trong mã phản ứng của tôi, tôi giải quyết vấn đề này bằng cách chỉ lưu trữ nội bộ số đã nhập và sau đó định dạng những gì được đặt trong trường. Vì vậy, backspace loại bỏ ký tự trước đó trong giá trị thực, không phải giá trị hiển thị.
David Baucum

5

Tôi đang sử dụng chức năng này để định dạng các số của Hoa Kỳ.

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

Nó chấp nhận hầu hết tất cả các cách có thể tưởng tượng để viết số điện thoại của Hoa Kỳ. Kết quả được định dạng thành dạng chuẩn là (987) 654-3210 x123


3

suy nghĩ ngược lại

Chỉ lấy các chữ số cuối cùng (tối đa 10) bỏ qua "1" đầu tiên.

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

ví dụ đầu vào / đầu ra khi bạn nhập

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

formatUSNumber('333')
// (333)

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

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

1
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

0

Đây là một trong đó sẽ chấp nhận cả số điện thoại và số điện thoại có phần mở rộng.

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

0

Bạn có thể sử dụng chức năng này để kiểm tra số điện thoại hợp lệ và chuẩn hóa chúng:

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

0

Tôi đã mở rộng câu trả lời của David Baucum để bao gồm hỗ trợ cho các phần mở rộng có độ dài lên đến 4 chữ số. Nó cũng bao gồm các dấu ngoặc đơn được yêu cầu trong câu hỏi ban đầu. Định dạng này sẽ hoạt động khi bạn nhập vào trường.

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;

0

Hầu hết tất cả những thứ này đều có vấn đề khi người dùng cố gắng xóa lùi các dấu phân cách, đặc biệt là từ giữa chuỗi.

Đây là một giải pháp jquery xử lý điều đó và cũng đảm bảo con trỏ ở đúng vị trí khi bạn chỉnh sửa:

//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 = '';        
    }
})

0

Các giải pháp trên là ưu việt hơn, đặc biệt nếu sử dụng Java và gặp phải nhiều số hơn 10 chữ số như tiền tố mã quốc tế hoặc các số máy lẻ bổ sung. Giải pháp này là cơ bản (tôi là người mới bắt đầu trong thế giới regex) và được thiết kế với số Điện thoại Hoa Kỳ và chỉ hữu ích cho các chuỗi chỉ có 10 số với một số ký tự định dạng hoặc có lẽ không có ký tự định dạng nào (chỉ 10 số ). Vì vậy, tôi sẽ đề xuất giải pháp này chỉ dành cho các ứng dụng bán tự động. Cá nhân tôi thích lưu trữ số chỉ dưới dạng 10 số mà không cần định dạng ký tự, nhưng cũng muốn có thể chuyển đổi hoặc xóa số điện thoại sang định dạng tiêu chuẩn mà mọi người bình thường và ứng dụng / điện thoại sẽ nhận ra ngay lập tức theo ý muốn.

Tôi xem qua bài đăng này đang tìm kiếm thứ gì đó tôi có thể sử dụng với ứng dụng dọn dẹp văn bản có khả năng PCRE Regex (nhưng không có chức năng java). Tôi sẽ đăng bài này ở đây cho những người có thể sử dụng một giải pháp Regex thuần túy đơn giản có thể hoạt động trong nhiều trình soạn thảo văn bản, trình dọn dẹp, trình mở rộng hoặc thậm chí một số trình quản lý khay nhớ tạm. Cá nhân tôi sử dụng Sublime và TextSoap. Giải pháp này được tạo ra cho Text Soap vì nó nằm trong thanh menu và cung cấp menu thả xuống, nơi bạn có thể kích hoạt các hành động thao tác văn bản trên những gì được chọn bởi con trỏ hoặc những gì trong khay nhớ tạm.

Cách tiếp cận của tôi về cơ bản là hai thay thế / tìm kiếm và thay thế regexes. Mỗi tìm kiếm thay thế và thay thế bao gồm hai regex, một để tìm kiếm và một để thay thế.

Thay thế / Tìm kiếm & Thay thế # 1

  • Thay thế / tìm kiếm & thay thế đầu tiên tách các số không phải số từ một số có 10 chữ số khác thành một chuỗi 10 chữ số.

Regex thay thế / tìm kiếm đầu tiên :\D

  • Chuỗi tìm kiếm này khớp với tất cả các ký tự không phải là chữ số.

Thay thế đầu tiên / Thay thế Regex: "" (không có gì, thậm chí không phải dấu cách)

  • Để trống hoàn toàn trường thay thế, không được tồn tại khoảng trắng kể cả khoảng trắng. Điều này sẽ dẫn đến việc xóa tất cả các ký tự không phải chữ số phù hợp. Bạn nên sử dụng 10 chữ số + ký tự định dạng trước khi thực hiện thao tác này và sử dụng các ký tự định dạng không có 10 chữ số.

Thay thế / Tìm kiếm & Thay thế # 2

  • Việc thay thế thứ hai / Tìm kiếm và thay thế tìm kiếm một phần của nhóm chụp hoạt động cho mã vùng $1, một nhóm chụp cho tập thứ hai trong ba số $2, và nhóm chụp cuối cùng cho tập cuối cùng của bốn số $3. Regex cho phần thay thế của thao tác sẽ chèn định dạng số điện thoại của Hoa Kỳ vào giữa nhóm chữ số được ghi lại.

Thay thế thứ hai / Tìm kiếm Regex:(\d{3})(\d{3})(\d{4})

Thay thế thứ hai / Thay thế Regex:\($1\) $2\-$3

  • Các dấu chéo ngược \thoát các ký tự đặc biệt (, ), (<-whitespace), và -vì chúng ta đang chèn chúng giữa số bị bắt của chúng tôi trong nhóm chụp $1, $2, & $3cho Mỹ mục đích định dạng số điện thoại.

  • Trong TextSoap, tôi đã tạo một trình dọn dẹp tùy chỉnh bao gồm hai hành động hoạt động thay thế, vì vậy trong thực tế, nó giống như thực thi một tập lệnh. Tôi chắc rằng giải pháp này có thể được cải thiện nhưng tôi mong đợi độ phức tạp sẽ tăng lên một chút. Một phiên bản cải tiến của giải pháp này được hoan nghênh như là một trải nghiệm học hỏi nếu bất kỳ ai muốn thêm vào điều này.


-2

Đối với số điện thoại của Hoa Kỳ

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

Hãy chia biểu thức chính quy này thành các đoạn nhỏ hơn để dễ hiểu.

  • /^\(?: Có nghĩa là số điện thoại có thể bắt đầu bằng một tùy chọn (.
  • (\d{3}): Sau tùy chọn (phải có 3 chữ số. Nếu số điện thoại không có a (, nó phải bắt đầu bằng 3 chữ số. Ví dụ: (308hoặc 308.
  • \)?: Có nghĩa là số điện thoại có thể có tùy chọn )sau 3 chữ số đầu tiên.
  • [- ]?: Tiếp theo số điện thoại có thể có dấu gạch ngang tùy chọn ( -) sau )nếu có hoặc sau 3 chữ số đầu tiên.
  • (\d{3}): Khi đó phải có 3 chữ số nữa. Ví dụ: (308)-135hoặc 308-135hoặc308135
  • [- ]?: Sau bộ 3 chữ số thứ hai, số điện thoại có thể có một dấu gạch ngang tùy chọn khác ( -). Ví dụ: (308)-135-hoặc 308-135-hoặc308135-
  • (\d{4})$/: Cuối cùng, số điện thoại phải kết thúc bằng bốn chữ số. Ví dụ: (308)-135-7895hoặc 308-135-7895hoặc 308135-7895hoặc3081357895 .

    Tài liệu tham khảo :

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


1
Sao chép nội dung từ các trang web khác và sau đó thậm chí không đăng liên kết là hành vi khá tệ: zparacha.com/phone_number_regex
Till Helge

1
Tôi xin lỗi, tôi không biết rằng chúng tôi phải đăng liên kết. Tôi nghĩ rằng chúng tôi phải cung cấp câu trả lời cho các truy vấn được đăng.
Bebu

5
Sẽ không bao giờ là ok khi làm cho một số khác hoạt động giống như của riêng bạn. Hãy nhớ cho lần sau rằng đăng liên kết có gì sai, nhưng sao chép (đặc biệt là không cung cấp liên kết) thì không. Và bạn luôn có tùy chọn chỉnh sửa câu trả lời của mình.
Till Helge

Downvotes vì ​​tác giả không trả lời cách thay số điện thoại như tác giả yêu cầu.
BrianHVB
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.