Regular Expression เพื่อฟอร์แมตหมายเลขโทรศัพท์ของสหรัฐอเมริกาใน Javascript


97

ฉันต้องการฟอร์แมตใหม่ (แทนที่ไม่ตรวจสอบ - มีข้อมูลอ้างอิงมากมายสำหรับการตรวจสอบความถูกต้อง) หมายเลขโทรศัพท์สำหรับแสดงใน Javascript นี่คือตัวอย่างของข้อมูลบางส่วน:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (ว่าง / ว่าง)
  • 1234567890

มีวิธีง่ายๆในการใช้นิพจน์ทั่วไปเพื่อทำสิ่งนี้หรือไม่? ฉันกำลังมองหาวิธีที่ดีที่สุดในการดำเนินการนี้ มีวิธีที่ดีกว่า?

ฉันต้องการฟอร์แมตหมายเลขดังต่อไปนี้: (123) 456-7890


3
รูปแบบเป้าหมายของคุณคือรูปแบบใด
จนถึง Helge

อันนี้: (123) 456-7890
Matt K

3
ฉันจะบอกว่าแค่ตัดอักขระที่ไม่ใช่ตัวเลขทั้งหมดแล้วใช้สตริงย่อยสามตัว
Wiseguy

2
@Wiseguy โปรดโพสต์เป็นคำตอบ (พร้อมตัวอย่าง) เนื่องจากนั่นคือสิ่งที่ OP ควรทำจริงๆ
Brian Driscoll

1
คุณต้องระบุด้วยว่ารูปแบบที่ยอมรับแต่ละรูปแบบแมปกับรูปแบบเป้าหมายอย่างไรซึ่งจะไม่ชัดเจนเลยหากอินพุตเป็นโมฆะ เว้นแต่คุณจะเต็มใจที่จะใช้เงื่อนไขพิเศษเพื่อกำจัดวัชพืชนั้นออกไป
จอน

คำตอบ:


240

สมมติว่าคุณต้องการรูปแบบ " (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"

2
สมบูรณ์แบบ; ขอบคุณ! อย่างไรก็ตามฉันเปลี่ยนreturn (!m) ? nullเป็นreturn (!m) ? ""หลังจากเพิ่มฟังก์ชันนี้
Matt K

2
บทเรียนที่ดีในการแก้ไขปัญหา ฉันพยายามคิดว่าจะจับคู่กรณีที่เป็นไปได้ทั้งหมดอย่างไร - คุณกำจัดสิ่งที่ไม่เกี่ยวข้องและดูว่ามีการจับคู่หรือไม่ ดีมาก.
Jkleg

2
FYI สิ่งนี้ใช้ไม่ได้กับหมายเลขเช่น + 1555-555-5555
จะ

'' + phoneNumberStringก็เหมือนกับphoneNumberString... มันเป็นสตริงแล้ว
YungGun

@YungGun เว้นแต่จะมีคนเรียกใช้ฟังก์ชันด้วยตัวเลขเช่นformatPhoneNumber(8001231234)
maerics

32

แนวทางแก้ไขที่เป็นไปได้:

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

27

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

alert(x);


1
ขอบคุณฌอนฉันชอบโซลูชันอินไลน์ง่ายๆสั้น ๆ ของคุณ
user752746

1
ขอบคุณสำหรับสิ่งนี้! ฉันเปลี่ยนx = x.replace(/[^\d]+/g, '') .replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');ให้ทำงานเพื่อเพิ่ม "+1" หน้าหมายเลขโทรศัพท์เช่น
Greg A

ขอบคุณ! นี่คือสิ่งที่ฉันต้องการ
Albert Hidalgo

8

คำตอบนี้ยืมมาจากคำตอบของ 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

วิธีนี้ใช้ได้ผลขณะพิมพ์โดยเพิ่มในรูปแบบที่ต้องการจากโปสเตอร์ต้นฉบับ หลังจากค้นหา 1.5 ชั่วโมงฉันดีใจที่ได้ลองใช้อันนี้!
funganthrax

ฉันเพิ่มวงเล็บรอบรหัสพื้นที่หากช่วยได้:(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}
Peter Hollingsworth

จริงๆแล้วปัญหาคือคุณไม่สามารถถอยกลับเหนือ "-" หรือช่องว่างจากสตริงกลางได้ คุณจำเป็นต้องป้องกันไม่ให้ฟอร์แมตใหม่เมื่อผู้ใช้กำลังถอยกลับ (เช่นnewstring.length < oldstring.lengthหรือเพื่อติดตามตำแหน่งเคอร์เซอร์และดูว่าเมื่อใดที่ผู้ใช้เพิ่งถอยกลับไปเหนือตัวคั่นเหล่านั้นเช่นif (cursorPosition === 4 && numericString.length > 3)
Peter Hollingsworth

ในรหัสการตอบกลับของฉันฉันสามารถแก้ไขปัญหานี้ได้โดยการจัดเก็บเฉพาะหมายเลขที่ป้อนไว้ภายในจากนั้นจัดรูปแบบสิ่งที่วางไว้ในฟิลด์ ดังนั้น backspace จะลบอักขระก่อนหน้าในค่าจริงไม่ใช่ค่าที่แสดง
David Baucum

5

ฉันกำลังใช้ฟังก์ชันนี้เพื่อจัดรูปแบบตัวเลขสหรัฐฯ

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


3

คิดย้อนกลับ

ใช้ตัวเลขสุดท้ายเท่านั้น (ไม่เกิน 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

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

นี่คือหมายเลขที่ยอมรับทั้งหมายเลขโทรศัพท์และหมายเลขโทรศัพท์ที่มีนามสกุล

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

คุณสามารถใช้ฟังก์ชันนี้เพื่อตรวจสอบหมายเลขโทรศัพท์ที่ถูกต้องและทำให้เป็นปกติได้:

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

ฉันได้ขยายคำตอบของ 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;

0

สิ่งเหล่านี้เกือบทั้งหมดมีปัญหาเมื่อผู้ใช้พยายาม backspace เหนือตัวคั่นโดยเฉพาะจากตรงกลางของสตริง

นี่คือโซลูชัน 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 = '';        
    }
})

0

โซลูชันข้างต้นดีกว่าโดยเฉพาะอย่างยิ่งหากใช้ Java และพบตัวเลขมากกว่า 10 หลักเช่นรหัสนำหน้ารหัสสากลหรือหมายเลขส่วนขยายเพิ่มเติม วิธีแก้ปัญหานี้เป็นพื้นฐาน (ฉันเป็นมือใหม่ในโลก regex) และได้รับการออกแบบโดยคำนึงถึงหมายเลขโทรศัพท์ของสหรัฐอเมริกาและมีประโยชน์สำหรับสตริงที่มีตัวเลขเพียง 10 ตัวซึ่งอาจมีการจัดรูปแบบอักขระบางตัวหรืออาจไม่มีการจัดรูปแบบอักขระเลย (มีเพียง 10 หมายเลข ). ด้วยเหตุนี้ฉันจึงขอแนะนำโซลูชันนี้สำหรับแอปพลิเคชันกึ่งอัตโนมัติเท่านั้น โดยส่วนตัวแล้วฉันชอบจัดเก็บตัวเลขเป็นตัวเลขเพียง 10 ตัวโดยไม่ต้องจัดรูปแบบตัวอักษร แต่ก็ต้องการที่จะสามารถแปลงหรือล้างหมายเลขโทรศัพท์ให้เป็นรูปแบบมาตรฐานที่คนทั่วไปและแอป / โทรศัพท์จะจดจำได้ทันทีตามต้องการ

ฉันเจอโพสต์นี้โดยมองหาสิ่งที่ฉันสามารถใช้กับแอพทำความสะอาดข้อความที่มีความสามารถ PCRE Regex (แต่ไม่มีฟังก์ชัน java) ฉันจะโพสต์สิ่งนี้ไว้ที่นี่สำหรับผู้ที่สามารถใช้โซลูชัน Regex ที่เรียบง่ายซึ่งสามารถทำงานได้กับโปรแกรมแก้ไขข้อความตัวทำความสะอาดตัวขยายหรือแม้แต่ผู้จัดการคลิปบอร์ด ส่วนตัวผมใช้ Sublime และ TextSoap โซลูชันนี้สร้างขึ้นสำหรับ Text Soap เนื่องจากอยู่ในแถบเมนูและมีเมนูแบบเลื่อนลงที่คุณสามารถเรียกใช้การดำเนินการจัดการข้อความกับสิ่งที่เคอร์เซอร์เลือกหรือสิ่งที่อยู่ในคลิปบอร์ด

แนวทางของฉันโดยพื้นฐานแล้วคือการแทนที่ / การค้นหาและการแทนที่ regexes สองครั้ง การค้นหาและแทนที่การแทนที่แต่ละรายการเกี่ยวข้องกับนิพจน์ทั่วไปสองรายการหนึ่งรายการสำหรับการค้นหาและอีกรายการหนึ่งสำหรับการแทนที่

การเปลี่ยนตัว / ค้นหาและแทนที่ # 1

  • การแทนที่ / ค้นหาและแทนที่ครั้งแรกจะดึงตัวเลขที่ไม่ใช่ตัวเลขจากตัวเลข 10 หลักเป็นสตริง 10 หลัก

การแทนที่ครั้งแรก / การค้นหา Regex:\D

  • สตริงการค้นหานี้จับคู่อักขระทั้งหมดที่ไม่ใช่ตัวเลข

First Substitution / Replace Regex: "" (ไม่มีแม้แต่ช่องว่าง)

  • เว้นช่องแทนที่ว่างไว้อย่างสมบูรณ์ไม่ควรมีช่องว่างรวมถึงช่องว่าง ซึ่งจะส่งผลให้อักขระที่ไม่ใช่ตัวเลขที่ตรงกันทั้งหมดถูกลบออก คุณควรใช้ตัวเลข 10 หลัก + การจัดรูปแบบอักขระก่อนการดำเนินการนี้และออกมาพร้อมกับตัวเลข 10 หลักที่มีการจัดรูปแบบอักขระ

การเปลี่ยนตัว / ค้นหาและแทนที่ # 2

  • การเปลี่ยนตัวผู้เล่นสอง / ค้นหาและแทนที่การค้นหาเป็นส่วนหนึ่งของกลุ่มจับการดำเนินงานสำหรับรหัสพื้นที่$1กลุ่มการจับภาพสำหรับชุดที่สองในสามของจำนวนและกลุ่มจับภาพสุดท้ายสำหรับชุดสุดท้ายของตัวเลขสี่$2 $3นิพจน์ทั่วไปสำหรับส่วนที่ใช้แทนของการดำเนินการจะแทรกการจัดรูปแบบหมายเลขโทรศัพท์ของสหรัฐอเมริกาไว้ระหว่างกลุ่มตัวเลขที่จับได้

การแทนที่ครั้งที่สอง / การค้นหา Regex:(\d{3})(\d{3})(\d{4})

การเปลี่ยนตัวครั้งที่สอง / แทนที่ Regex:\($1\) $2\-$3

  • เครื่องหมาย\หนีตัวอักษรพิเศษ(, ), (<-whitespace) และ-เนื่องจากเราใส่ไว้ระหว่างตัวเลขจับเราในกลุ่มจับภาพ$1, $2และ$3หมายเลขโทรศัพท์ของสหรัฐอเมริกาจัดรูปแบบวัตถุประสงค์

  • ใน TextSoap ฉันได้สร้างตัวล้างแบบกำหนดเองซึ่งรวมถึงการดำเนินการการดำเนินการทดแทนสองรายการดังนั้นในทางปฏิบัติจึงรู้สึกเหมือนกับการเรียกใช้สคริปต์ ฉันแน่ใจว่าโซลูชันนี้สามารถปรับปรุงได้ แต่ฉันคาดหวังว่าจะมีความซับซ้อนเพิ่มขึ้นเล็กน้อย เวอร์ชันปรับปรุงของโซลูชันนี้ยินดีเป็นประสบการณ์การเรียนรู้หากใครต้องการเพิ่มสิ่งนี้


-2

สำหรับหมายเลขโทรศัพท์ของสหรัฐอเมริกา

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

ลองแบ่งนิพจน์ทั่วไปนี้เป็นส่วนย่อย ๆ เพื่อให้เข้าใจง่าย

  • /^\(?: (หมายถึงว่าหมายเลขโทรศัพท์ที่อาจเริ่มต้นด้วยตัวเลือก
  • (\d{3}): หลังจากตัวเลือก(ต้องมีตัวเลข 3 หลัก หากหมายเลขโทรศัพท์ไม่มี a (ต้องขึ้นต้นด้วย 3 หลัก เช่น(308หรือ308.
  • \)?: หมายความว่าหมายเลขโทรศัพท์สามารถมีตัวเลือกเสริม)หลัง 3 หลักแรกได้
  • [- ]?: ถัดไปหมายเลขโทรศัพท์สามารถมียัติภังค์เสริม ( -) หลัง)ถ้ามีอยู่หรือหลัง 3 หลักแรก
  • (\d{3}): จากนั้นจะต้องมีตัวเลขอีก 3 หลัก เช่น(308)-135หรือ308-135หรือ308135
  • [- ]?: หลังจากชุดที่สองของตัวเลข 3 หลักหมายเลขโทรศัพท์สามารถมียัติภังค์ ( -) ก็ได้ เช่น(308)-135-หรือ308-135-หรือ308135-
  • (\d{4})$/: สุดท้ายหมายเลขโทรศัพท์จะต้องลงท้ายด้วยตัวเลขสี่หลัก เช่น(308)-135-7895หรือ308-135-7895หรือ308135-7895หรือ3081357895.

    อ้างอิง:

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


1
การคัดลอกเนื้อหาจากเว็บไซต์อื่นแล้วไม่โพสต์ลิงก์นั้นถือเป็นพฤติกรรมที่ไม่ดีเลยทีเดียว: zparacha.com/phone_number_regex
จนถึง

1
ฉันขอโทษฉันไม่รู้ว่าเราต้องโพสต์ลิงก์ ฉันคิดว่าเราต้องตอบคำถามที่โพสต์ไว้เท่านั้น
Bebu

5
มันเป็นไม่เคยตกลงที่จะให้ดูผลงานอื่น someones เหมือนของคุณเอง โปรดจำไว้ในครั้งต่อไปว่าไม่มีอะไรผิดปกติในการโพสต์ลิงก์ แต่จะไม่คัดลอก (โดยเฉพาะอย่างยิ่งโดยไม่ให้ลิงก์) และคุณมีตัวเลือกในการแก้ไขคำตอบของคุณเสมอ
จนถึง Helge

โหวตลงเนื่องจากผู้เขียนไม่ได้ตอบวิธีการแทนที่หมายเลขโทรศัพท์ตามที่ผู้เขียนร้องขอ
BrianHVB
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.