วิธีตรวจสอบหมายเลขโทรศัพท์โดยใช้ regex


920

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

  • 1-234-567-8901
  • 1-234-567-8901 x1234
  • 1-234-567-8901 ext1234
  • 1 (234) 567-8901
  • 1.234.567.8901
  • 1/234/567/8901
  • 12345678901

ฉันจะตอบด้วยความพยายามในปัจจุบันของฉัน แต่ฉันหวังว่าจะมีใครบางคนมีสิ่งที่ดีกว่าและ / หรือสวยงามกว่า


3
BTW คุณควรระบุภาษาที่คุณใช้ เอนจิน regex บางตัวนั้นมีไวยากรณ์เหมือนกัน
AndrewJFord

9
ดูเหมือนว่าคุณจะออกจากตัวเลือก +1 แทนเพียง 1 แม้ว่าคำตอบจะครอบคลุมกรณีนี้
เอริค

153
ไม่ต้องการหมายเลขโทรศัพท์ในสหรัฐฯทั้งหมด555นอกเหนือไปจากนี้911หรือ
Andrew Grimm

41
ตรงกันข้ามคำนำหน้า 555 ถูกสงวนไว้สำหรับหมายเลขโทรศัพท์ปลอม หมายเลขเหล่านี้รับประกันว่าจะไม่เชื่อมต่อกับหมายเลขโทรศัพท์จริงดังนั้นจึงมักใช้ในโทรทัศน์และภาพยนตร์เพื่อให้แน่ใจว่าผู้ชมจะไม่พยายามโทรไปที่หมายเลขและท้ายที่สุดจะก่อกวนผู้บริสุทธิ์ที่ไม่ดี
Rushinge

49
@rushinge ในขณะที่เป็นความจริงทศวรรษที่ผ่านมามันไม่มีจริง คำนำหน้า 555 ยังคงเป็นพิเศษ แต่รับประกันว่าจะมีหมายเลขเล็ก ๆ เท่านั้นที่จะยกเลิกโดยไม่ต้องเชื่อมต่อ 555-0100 ถึง 555-0199 แต่ฉันค่อนข้างมั่นใจว่าแอนดรูกำลังล้อเล่นอยู่แล้ว
Adam Davis

คำตอบ:


515

ตัวเลือกที่ดีกว่า ... เพียงดึงอักขระที่ไม่ใช่ตัวเลขทั้งหมดลงในอินพุต (ยกเว้น 'x' และเครื่องหมาย '+' นำหน้า) ดูแลเนื่องจากแนวโน้มของอังกฤษในการเขียนตัวเลขในรูปแบบที่ไม่ได้มาตรฐาน+44 (0) ...เมื่อถูกขอให้ใช้คำนำหน้าสากล (ในกรณีเฉพาะนั้นคุณควรทิ้ง(0)ทั้งหมด)

จากนั้นคุณจะพบกับค่าเช่น:

 12345678901
 12345678901x1234
 345678901x1234
 12344678901
 12345678901
 12345678901
 12345678901
 +4112345678
 +441234567890

จากนั้นเมื่อคุณแสดงให้จัดรูปแบบเนื้อหาหัวใจของคุณ เช่น

  1 (234) 567-8901
  1 (234) 567-8901 x1234

35
รหัสการจัดรูปแบบจะเสียเวลาหากตัวเลขได้รับอนุญาตให้มาจากนอกสหรัฐอเมริกา
Daniel Earwicker

26
สิ่งนี้เป็นสิ่งที่ดีและทั้งหมด แต่ไม่ได้ตรวจสอบสิ่งที่ป้อนจริง ๆ แล้วเป็นหมายเลขโทรศัพท์ ตัวอย่างเช่นจะเกิดอะไรขึ้นหากผู้ใช้ไม่ได้ป้อน 10 หลักที่ต้องการ ควรรวมกับการตรวจสอบ regex ที่ดี
Hugh Jeffner

108
การพิจารณาคำถามนั้นเกี่ยวกับการตรวจสอบความถูกต้อง - นี่เป็นคำตอบที่ไม่ดีจริงๆ
PlexQ

15
@PlexQ ฉันไม่เห็นด้วย ปัญหาดั้งเดิมคือพยายามจัดการการตรวจสอบหมายเลขโทรศัพท์เนื่องจากพยายามจัดการตัวเลือกการจัดรูปแบบที่เป็นไปได้ทั้งหมด แทนที่จะพยายามที่จะแก้ปัญหาทั้งหมดนั้นให้นำอินพุตและ "pre-strip" ของการจัดรูปแบบทั้งหมดของปุยจนกว่าคุณจะมีเพียง "หมายเลข" การทำเช่นนี้ช่วยแก้ปัญหา 2 ประการ - การทดสอบผลลัพธ์เป็นเรื่องง่ายและตอนนี้คุณสามารถมั่นใจได้ว่าค่าที่แสดงผลออกมาสำหรับการแสดงผลสามารถจัดรูปแบบได้อย่างสม่ำเสมอ ความคิดเห็นแรกเกี่ยวกับคำตอบนี้เกี่ยวกับ "ถุงมือของผู้ร้องเรียน" คือการอ่านที่ดี ... บางครั้งคำตอบของปัญหาคือวิธีการที่แตกต่างกัน
scunliffe

29
นี่เป็นคำตอบที่ได้รับการโหวตอย่างสูงอย่างไร? สิ่งนี้ไม่ได้ตรวจสอบอะไรเลย สิ่งที่แย่กว่านั้นคือคำถามการตรวจสอบความถูกต้องหมายเลขโทรศัพท์อื่น ๆ อ้างอิงคำถามนี้ ...
jlars62

303

ปรากฎว่ามีบางสิ่งที่พิเศษสำหรับเรื่องนี้อย่างน้อยก็ในอเมริกาเหนือเรียกว่าNANP NANP

คุณต้องระบุสิ่งที่คุณต้องการอย่างแน่นอน ตัวคั่นทางกฎหมายคืออะไร ช่องว่างขีดคั่นและจุด? ไม่อนุญาตให้ใช้ตัวคั่น สามารถผสมตัวคั่น (เช่น + 0.111-222.3333) ได้หรือไม่ ส่วนขยาย (เช่น 111-222-3333 x 44444) จะได้รับการจัดการอย่างไร แล้วตัวเลขพิเศษเช่น 911 ล่ะ รหัสพื้นที่จะเป็นตัวเลือกหรือจำเป็นหรือไม่?

นี่คือ regex สำหรับตัวเลข 7 หรือ 10 หลักโดยอนุญาตให้ใช้ตัวขยายได้ตัวคั่นคือช่องว่างเครื่องหมายขีดคั่นหรือจุด:

^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$

7
นี่คือไม่มีส่วนขยาย (ฉันให้ผู้ใช้ป้อน ext ในฟิลด์แยก): ^ (?: (?: \ +? 1 \ s * (?: [.-] \ s *)?)? (? : (\ s * ([2-9] 1 [9/2] | [2-9] [02-8] 1 | [2-9] [02-8] [9/2]) \ s *) | ([2-9] 1 [9/2] | [2-9] [02-8] 1 | [2-9] [02-8] [9/2])) \ s * (: [ .-] \ s *)) ([2-9] 1 [9/2] |? [2-9] [9/2] 1 | [2-9] [9/2] {2}) \ s * (?: [.-] \ s *)? ([0-9] {4}) $
aarona

18
นี่คือรุ่นที่ตรงกับหมายเลขโทรศัพท์ 10 หลักเท่านั้น (ไม่ใช่ 7 หลักเช่น 843-1212): /(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})/
Brian Armstrong

8
10 หลักยอมรับ () รอบรหัสพื้นที่และไม่อนุญาตให้นำหน้า 1 เป็นรหัสประเทศ(?:(?:(\s*\(?([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\)?\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})
Brooke

5
@ สตีเว่นโซโรกะฉันมีหนังสือของเจฟฟรีย์ฟรีดอยู่ข้างๆฉันบนโต๊ะของฉันตลอดสองปีที่ผ่านมาเนื่องจากการแสดงออกปกติเป็นส่วนสำคัญของงานของฉัน ใช้เวลาสักครู่ในการเข้าใจการแสดงออกปกติ บางครั้งผู้อ่านของไซต์นี้กำลังมองหาวิธีแก้ไขปัญหาที่มีอยู่เดิมแทนที่จะเขียนของตัวเองโดยเฉพาะในโดเมนที่มีตัวพิมพ์มุมมากเช่นการแสดงหมายเลขโทรศัพท์
Justin R.

7
@ fatcat1111 ฉันเข้าใจว่า แต่คำตอบส่วนใหญ่ที่นี่คือ "ฉันด้วย" ประเภทของการแสดงออกปกติครั้งเดียวที่มีแนวโน้มว่าจะไม่เหมาะกับกรณีมุมของคุณ สิ่งเหล่านี้จะจบลงในเว็บไซต์ทั้งหมดที่ฉันพยายามใช้และฉันไม่สามารถป้อนรหัสไปรษณีย์หรือหมายเลขโทรศัพท์หรือที่อยู่อีเมลของฉันได้เพราะมีคนใช้การแสดงออกปกติแบบครึ่งหน้า (เช่น: + เป็นอักขระที่ถูกต้องในที่อยู่อีเมล ) คำตอบที่ดีที่สุดในหน้านี้ชี้ผู้ใช้ไปยังห้องสมุดไม่ใช่เพื่อ regexes ผ้าเช็ดปาก
Steven Soroka

298
.*

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

ฉันจะพิจารณารายการใด ๆ ต่อไปนี้เป็นรายการที่ถูกต้องในเว็บไซต์:

"123 456 7890 until 6pm, then 098 765 4321"  
"123 456 7890 or try my mobile on 098 765 4321"  
"ex-directory - mind your own business"

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

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

11
นอกจากนี้บทบาทของการตรวจสอบก็เพื่อเตือนผู้คนให้เพิ่มรหัสพื้นที่เป็นต้นว่าพวกเขาอาจจำไม่ได้ว่าจะเพิ่ม แต่อย่างใดซึ่งไม่สามารถเดาได้หลังจากความจริง
Ben McIntyre

29
@Pointy แต่การตรวจสอบ regex จะไม่ช่วยคุณ วิธีการหนึ่งเดียวในการตรวจสอบความถูกต้องจริงถ้าหมายเลขโทรศัพท์ถูกต้องคือการส่งข้อความ (ในกรณีของมือถือ) และตรวจสอบให้แน่ใจว่าผู้ใช้ยืนยันโดยใช้รหัสยืนยันบางประเภท นี่คือสิ่งที่คุณทำเมื่อความถูกต้องของจำนวนนั้นมีความสำคัญ ทุกอย่างมีไว้เพื่อความสะดวกของผู้ใช้ในการป้องกันความผิดพลาดบางอย่าง (แต่ไม่ใช่ทั้งหมด) และไม่ได้ตรวจสอบสิ่งใด
Alex B

14
เย็น. หมายเลขโทรศัพท์ของฉันคือ1' หรือ 1 = 1 - Pwned ดูxkcd.com/327 และowasp.org/index.php/Testing_for_SQL_Inject_(OWASP-DV-005)
Aaron Newton

171

ฉันขอแนะนำให้ดูที่ห้องสมุด Google " libphonenumber " ฉันรู้ว่ามันไม่ใช่ regex แต่ทำในสิ่งที่คุณต้องการ

ตัวอย่างเช่นจะรับรู้ว่า:

15555555555

เป็นตัวเลขที่เป็นไปได้ แต่ไม่ใช่ตัวเลขที่ถูกต้อง นอกจากนี้ยังสนับสนุนประเทศนอกสหรัฐอเมริกา

ไฮไลท์ของฟังก์ชั่น:

  • แยก / จัดรูปแบบ / ตรวจสอบหมายเลขโทรศัพท์สำหรับทุกประเทศ / ภูมิภาคของโลก
  • getNumberType- รับชนิดของตัวเลขตามตัวเลขนั้น สามารถแยกแยะโทรศัพท์พื้นฐาน, โทรศัพท์มือถือ, อัตราค่าโทร, ค่าใช้จ่ายร่วม, VoIP และหมายเลขส่วนตัว (ทุกครั้งที่ทำได้)
  • isNumberMatch - รับระดับความเชื่อมั่นว่าตัวเลขทั้งสองอาจเหมือนกันหรือไม่
  • getExampleNumber/getExampleNumberByType - ให้หมายเลขตัวอย่างที่ถูกต้องสำหรับทุกประเทศ / ภูมิภาคโดยมีตัวเลือกในการระบุประเภทของหมายเลขโทรศัพท์ตัวอย่างที่จำเป็น
  • isPossibleNumber - คาดเดาได้อย่างรวดเร็วว่าตัวเลขเป็นหมายเลขโทรศัพท์ที่เป็นไปได้หรือไม่โดยใช้ข้อมูลความยาวเท่านั้นเร็วกว่าการตรวจสอบความถูกต้องเต็มรูปแบบ
  • isValidNumber - การยืนยันหมายเลขโทรศัพท์สำหรับภูมิภาคโดยใช้ข้อมูลความยาวและคำนำหน้า
  • AsYouTypeFormatter - จัดรูปแบบหมายเลขโทรศัพท์แบบทันทีเมื่อผู้ใช้ป้อนตัวเลขแต่ละหลัก
  • findNumbers - ค้นหาตัวเลขในการป้อนข้อความ
  • PhoneNumberOfflineGeocoder - ให้ข้อมูลทางภูมิศาสตร์ที่เกี่ยวข้องกับหมายเลขโทรศัพท์

ตัวอย่าง

ปัญหาที่ใหญ่ที่สุดกับการตรวจสอบหมายเลขโทรศัพท์นั้นขึ้นอยู่กับวัฒนธรรมเป็นอย่างมาก

  • สหรัฐอเมริกา
    • (408) 974–2042หมายเลขสหรัฐที่ถูกต้องคือ
    • (999) 974–2042คือไม่ได้เป็นที่ถูกต้องจำนวนบาท
  • ออสเตรเลีย
    • 0404 999 999เป็นหมายเลขออสเตรเลียที่ถูกต้อง
    • (02) 9999 9999เป็นหมายเลขออสเตรเลียที่ถูกต้อง
    • (09) 9999 9999คือไม่ได้เป็นที่ถูกต้องจำนวนออสเตรเลีย

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

ฉันขอแนะนำให้ข้ามการแสดงออกปกติอย่างง่าย ๆ เพื่อทดสอบหมายเลขโทรศัพท์ของคุณและใช้ห้องสมุดเช่น Google libphonenumber (ลิงก์ไปยังโครงการ GitHub)GitHub)

แนะนำ libphonenumber!

ใช้หนึ่งในตัวอย่างที่ซับซ้อนมากขึ้นของ1-234-567-8901 x1234คุณคุณจะได้รับข้อมูลต่อไปนี้libphonenumber(ลิงก์ไปยังการสาธิตออนไลน์) :

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results:

E164 format                    +12345678901
Original format                (234) 567-8901 ext. 123
National format                (234) 567-8901 ext. 123
International format           +1 234-567-8901 ext. 123
Out-of-country format from US  1 (234) 567-8901 ext. 123
Out-of-country format from CH  00 1 234-567-8901 ext. 123

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

โบนัสlibphonenumberมีชุดข้อมูลจำนวนหนึ่งเพื่อตรวจสอบความถูกต้องของหมายเลขโทรศัพท์เช่นกันดังนั้นการตรวจสอบหมายเลขเช่น+61299999999(รุ่นสากล(02) 9999 9999) จะส่งกลับเป็นหมายเลขที่ถูกต้องพร้อมการจัดรูปแบบ:

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results

E164 format                    +61299999999
Original format                61 2 9999 9999
National format                (02) 9999 9999
International format           +61 2 9999 9999
Out-of-country format from US  011 61 2 9999 9999
Out-of-country format from CH  00 61 2 9999 9999

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

PhoneNumberOfflineGeocoder Results
Location        Australia

PhoneNumberToTimeZonesMapper Results
Time zone(s)    [Australia/Sydney]

แต่หมายเลขโทรศัพท์ของออสเตรเลียที่ไม่ถูกต้อง ( (09) 9999 9999) ส่งคืนว่าไม่ใช่หมายเลขโทรศัพท์ที่ถูกต้อง

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     false

เวอร์ชันของ Google มีรหัสสำหรับ Java และ Javascript แต่ผู้คนยังใช้ห้องสมุดสำหรับภาษาอื่น ๆ ที่ใช้ชุดข้อมูลหมายเลขโทรศัพท์ของ Google i18n:

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


สังเกตว่าขณะนี้ยังมีพอร์ต Go ที่: github.com/ttacon/libphonenumber
michaelhanson

เมื่อตรวจสอบว่าเป็นตัวเลขที่เป็นไปได้คุณไม่จำเป็นต้องระบุรหัสประเทศ? ฉันกำลังใช้เวอร์ชั่น PHP และหากฉันป้อนหมายเลขอังกฤษเช่น (แทนที่ 0 ด้วยตัวเลขจริง) 07700000000ฉันได้รับMissing or invalid default region.ข้อผิดพลาด แต่ถ้าฉันระบุรหัสประเทศมันจะผ่าน
BugHunterUK

FYI: ห้องสมุดนี้ไม่รองรับบางประเทศphpinterviewquestions.co.in/blog/ionic/ …
sijo vijayan

1
@BugHunterUK (และทุกคนที่เจอคำถามนี้และสงสัยในสิ่งเดียวกัน) เมื่อทำการแจงตัวเลขคุณสามารถระบุภูมิภาคที่คาดไว้และห้องสมุดจะค้นหาหมายเลขที่ไม่ใช่นานาชาติในภูมิภาคนั้น หากคุณไม่ได้ระบุไว้ระบบจะปฏิเสธสิ่งใดก็ตามที่ไม่อยู่ในรูปแบบสากลที่ถูกต้อง
IMSoP

พิจารณาgithub.com/nyaruka/phonenumbersเนื่องจากเป็นแพคเกจ Go "ทางการ" ที่ Google แนะนำแทนที่จะเป็น libphonenumber
DeeZone

78

/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i

การแข่งขันครั้งนี้:

 - (+351) 282 43 50 50
 - 90191919908
 - 555-8909
 - 001 6867684
 - 001 6867684x1
 - 1 (234) 567-8901
 - 1-234-567-8901 x1234
 - 1-234-567-8901 ext1234
 - 1-234 567.89/01 ext.1234
 - 1(234)5678901x1234
 - (123)8575973
 - (0055)(123)8575973

ในวันที่ $ n จะประหยัด:

  1. ตัวบ่งชี้ประเทศ
  2. หมายเลขโทรศัพท์
  3. ส่วนขยาย

คุณสามารถทดสอบได้ที่https://www.regexpal.com/?fam=99127


นี่คือ regex ที่ครอบคลุมที่สุดที่ฉันเคยเห็น มันง่ายที่จะได้รับรอบจนกว่าคุณจะลบ^และ$หรืออื่น ๆ ที่ฉันสามารถที่จะได้รับรอบโดยใช้[111] [111] [1111]หรือ111--111--1111และไม่ชอบ (ขออภัยลบความคิดเห็นล่าสุดของฉัน)
bafromca

คุณกรุณาวลีอีกครั้งได้ไหม ฉันไม่เข้าใจสิ่งนี้: "มันเป็นเรื่องง่ายที่จะจัดการจนกระทั่งคุณลบ ^ และ $ หรืออื่น ๆ ฉันสามารถใช้มันได้โดยใช้ [111] [111] [1111]" มันไม่ได้หมายความว่ามันจะตรวจสอบ '[111] [111] [1111] เมื่อคุณใช้เวลา^และ$?
Ismael Miguel

ฉันได้รอบ regex ของคุณโดยใช้[111] [111] [1111]และ111--111--1111จนกว่าฉันจะลบออก^และ$จาก regex ไม่
bafromca

11
^^^ นี่เป็นตัวอย่างที่ดีว่าทำไมหัวข้อความคิดเห็นไม่ควรไปแชท ฉันสนใจที่การสนทนานี้จะเปิดออกและต้องการทราบว่า ReGex นี้แข็งแรงพอที่จะใช้ในแอปของฉันหรือไม่ น่าเสียดายที่การสนทนาของแชทหายไป
Matt Cashatt

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

63

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

1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?

นี่คือสคริปต์ Perl เพื่อทดสอบ เมื่อคุณตรงกัน $ 1 จะมีรหัสพื้นที่ $ 2 และ $ 3 มีหมายเลขโทรศัพท์และ $ 5 มีส่วนขยาย สคริปต์ทดสอบของฉันดาวน์โหลดไฟล์จากอินเทอร์เน็ตและพิมพ์หมายเลขโทรศัพท์ทั้งหมดในนั้น

#!/usr/bin/perl

my $us_phone_regex =
        '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?';


my @tests =
(
"1-234-567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1 (234) 567-8901",
"1.234.567.8901",
"1/234/567/8901",
"12345678901",
"not a phone number"
);

foreach my $num (@tests)
{
        if( $num =~ m/$us_phone_regex/ )
        {
                print "match [$1-$2-$3]\n" if not defined $4;
                print "match [$1-$2-$3 $5]\n" if defined $4;
        }
        else
        {
                print "no match [$num]\n";
        }
}

#
# Extract all phone numbers from an arbitrary file.
#
my $external_filename =
        'http://web.textfiles.com/ezines/PHREAKSANDGEEKS/PnG-spring05.txt';
my @external_file = `curl $external_filename`;
foreach my $line (@external_file)
{
        if( $line =~ m/$us_phone_regex/ )
        {
                print "match $1 $2 $3\n";
        }
}

แก้ไข:

คุณสามารถเปลี่ยน \ W * เป็น \ s * \ W? \ s * ใน regex เพื่อทำให้แน่นขึ้นเล็กน้อย ฉันไม่ได้คิดถึง regex ในแง่ของการพูดการตรวจสอบความถูกต้องของผู้ใช้ในแบบฟอร์มเมื่อฉันเขียน แต่การเปลี่ยนแปลงนี้ทำให้สามารถใช้ regex เพื่อจุดประสงค์นั้นได้

'1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';

2
FYI regex ยังตรงกัน: (4570457-6789ซึ่งจะเป็นพิมพ์ผิดที่ค่อนข้างธรรมดา กลุ่มการแข่งขันจะเบ้เช่นกัน: rubular.com/r/TaTP0mHL5c
SooDesuNe

@SooDesuNe กำลังเตรียม(^|[^\d\n])(ด้วยการเปิดแฟล็กหลายรายการ) เพื่อหลีกเลี่ยงปัญหาทั่วไปโดยตรวจสอบให้แน่ใจว่าไม่ได้มีบางสิ่งที่เป็นตัวเลขนำหน้าในทันที
btown

โปรดทราบว่านี่คือศูนย์กลางในอเมริกาเหนือ - พลาด "44 7911 123456"
Ben Wheeler

43

ฉันตอบคำถามนี้กับคำถาม SO อื่นก่อนตัดสินใจที่จะรวมคำตอบของฉันไว้เป็นคำตอบในหัวข้อนี้เพราะไม่มีใครตอบคำถามที่ต้องการ / ไม่ต้องการรายการเพียงแค่ส่ง regexs: Regex ทำงานผิดพลาดจับคู่สิ่งที่ไม่คาดคิด

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

แผ่นโกงด่วน

  • เริ่มการแสดงออก: /^
  • หากคุณต้องการพื้นที่ให้ใช้: [\s]หรือ\s
  • หากคุณต้องการที่จะต้องวงเล็บใช้: และ[(] [)]การใช้\(และ\)น่าเกลียดและอาจทำให้สับสน
  • หากคุณต้องการให้อะไรก็ได้ให้ใส่ ?หลังจากนั้น
  • หากคุณต้องการยัติภังค์เพียงพิมพ์-หรือ[-]หรือหากคุณไม่ใส่อักขระตัวแรกหรือตัวสุดท้ายในซีรีส์ของตัวละครอื่นคุณอาจต้องหลบหนี: \-
  • หากคุณต้องการยอมรับตัวเลือกที่แตกต่างกันในช่องใส่ตัวยึดไว้รอบตัวเลือก: [-.\s]จะต้องมีเครื่องหมายยัติภังค์ระยะเวลาหรือเว้นวรรค เครื่องหมายคำถามหลังเครื่องหมายวงเล็บสุดท้ายจะทำให้เป็นตัวเลือกสำหรับช่องนั้น
  • \d{3}: ต้องมีตัวเลข 3 หลัก: 000-999 จดชวเลข [0-9][0-9][0-9]ชวเลข
  • [2-9] : ต้องการตัวเลข 2-9 สำหรับช่องนั้น
  • (\+|1\s)?: ยอมรับ "บวก" หรือ 1 และเว้นวรรค (ไพพ์ไลน์|, คือ "หรือ") และทำให้เป็นตัวเลือก ต้องใช้เครื่องหมาย "บวก"
  • หากคุณต้องการให้หมายเลขเฉพาะตรงกับสล็อตให้ป้อน: [246]จะต้องมี 2, 4 หรือ 6 [77|78]จะต้องมี 77 หรือ 78
  • $/ : สิ้นสุดการแสดงออก

1
สิ่งนี้มีประโยชน์มาก แต่ฉันสงสัยและมองหาการแสดงออก {min, max} คุณช่วยได้ไหม
Ataboy Josef

หากเป็นตัวเลขหลักเดียวที่เรากำลังพูดถึง (และคุณสามารถทำให้มันตรงกับที่) ดู[2-9]บล็อกฉันใส่มี นั่นหมายความว่าขั้นต่ำของคุณคือ 2 และสูงสุดของคุณคือ 9 ปรับตาม
vapcguy

30

ฉันเขียนง่ายที่สุด (แม้ว่าฉันไม่ต้องการจุดใน)

^ ([0-9 \ (\) \ / \ + \ -] *) $

ตามที่ระบุไว้ด้านล่างจะตรวจสอบเฉพาะอักขระเท่านั้นไม่ใช่โครงสร้าง / คำสั่ง


38
สิ่งนี้ตรวจสอบความถูกต้องของตัวเลขที่ไม่ถูกต้องทางเทคนิค เช่น "- + () () ()) ())))" เรียนรู้วิธีอ่านนิพจน์ทั่วไปเพื่อให้คุณสามารถเข้าใจสิ่งที่คุณทำ
Steven Soroka

3
@ StevenSoroka ในทางเทคนิคอาจทำให้เกิดกรณีที่ไม่ถูกต้องจำนวนมาก แต่เมื่อเราคิดที่จะช่วยเหลือผู้ใช้ในการหลีกเลี่ยงข้อผิดพลาดทั่วไปด้วยวิธีแก้ปัญหาที่ง่ายที่สุดนี่คือหนทางที่จะไป :)
happyhardik

2
การจับคู่นี้คือ white space, บรรทัดว่างเปล่า
Wasim A.

1
@HappyHardik จริง ง่ายและมีประสิทธิภาพสำหรับการตรวจสอบขั้นพื้นฐานให้ผู้ใช้พิมพ์มากกว่าหนึ่งจุดเส้นประวงเล็บหรือบวก
dijipiji

เพียงแค่ใช้มันและมันก็ผิดในหลาย ๆ ด้าน ตัวอย่างเช่นหมายเลขโทรศัพท์ในสหราชอาณาจักรอาจเริ่มต้นด้วย +44 หรือเบอร์โทรศัพท์อาจมี (0) อยู่ข้างใน แต่สิ่งนี้ไม่ถูกต้องตามนิพจน์ปกติของคุณ ฉันจะแนะนำคำตอบของ @Ismael Miguel มันใช้งานได้ดีและฉันขอแนะนำให้คุณแก้ไขคำตอบของคุณ
Stelios Voskos

22

หากคุณต้องการตรวจสอบว่าคุณไม่มีขยะสุ่มในฟิลด์ (เช่นจากผู้ส่งอีเมลแบบฟอร์ม) regex นี้ควรทำอย่างดี:

^[0-9+\(\)#\.\s\/ext-]+$

โปรดทราบว่ามันไม่มีกฎพิเศษใด ๆ สำหรับจำนวนหลักหรือจำนวนที่ถูกต้องในตัวเลขเหล่านั้นเพียงตรวจสอบว่ามีเพียงตัวเลขหลักวงเล็บเครื่องหมายขีดคั่นบวกเครื่องหมายวรรคช่องว่างเครื่องหมายดอกจันเครื่องหมายจุลภาคหรือตัวอักษรe, x, tที่มีอยู่

ควรเข้ากันได้กับตัวเลขระหว่างประเทศและรูปแบบการแปล คุณเล็งเห็นถึงความจำเป็นในการอนุญาตให้ใช้วงเล็บเหลี่ยมหยิกหรือมุมสำหรับบางภูมิภาคหรือไม่? (ปัจจุบันยังไม่รวม)

หากคุณต้องการรักษากฎต่อหลัก (เช่นในรหัสพื้นที่ของสหรัฐอเมริกาและรหัสนำหน้า (รหัสแลกเปลี่ยน) ต้องอยู่ในช่วง 200-999) ขอให้คุณโชคดี การรักษากฎเกณฑ์ที่ซับซ้อนซึ่งอาจล้าสมัย ณ จุดใด ๆ ในอนาคตโดยประเทศใด ๆ ในโลกไม่สนุก

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


22

โปรดทราบว่า()อักขระการลอกไม่ทำงานสำหรับรูปแบบการเขียนหมายเลขสหราชอาณาจักรที่ใช้กันทั่วไป: +44 (0) 1234 567890ซึ่งหมายถึงการหมุนหมายเลขระหว่างประเทศ:
+441234567890
หรือในการหมุนหมายเลขสหราชอาณาจักร01234567890


15

คุณได้ดูRegExLib แล้วหรือยัง

การป้อนหมายเลขโทรศัพท์ในสหรัฐอเมริกานำมาซึ่งรายการความเป็นไปได้ค่อนข้างมาก


3
นี่เป็นวิธีที่ดีในการรวมข้อบกพร่องที่คลุมเครือเข้ากับโค้ดของคุณ
Tom Lord

12

ความพยายามของฉันที่ regex ไม่ จำกัด :

/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/

ยอมรับ:

+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww

เสีย:

mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911

มันขึ้นอยู่กับคุณที่จะฆ่ามันเพื่อแสดง หลังจากตรวจสอบอาจเป็นตัวเลขแม้ว่า


12

ฉันพบว่าสิ่งนี้ทำงานได้ค่อนข้างดี:

^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$

มันใช้งานได้กับรูปแบบตัวเลขเหล่านี้:

1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
1-234-567-8901 ext. 1234
(+351) 282 433 5050

ตรวจสอบให้แน่ใจว่าใช้ค่าสถานะส่วนกลางและหลายบรรทัดเพื่อให้แน่ใจ

ลิงก์: http://www.regexr.com/3bp4b


11

หากคุณกำลังพูดถึงการตรวจสอบความถูกต้องของแบบฟอร์ม regexp เพื่อตรวจสอบความหมายที่ถูกต้องรวมทั้งข้อมูลที่ถูกต้องจะมีความซับซ้อนอย่างมากเนื่องจากประเทศและมาตรฐานผู้ให้บริการที่แตกต่างกัน มันจะยากที่จะติดตาม

ฉันตีความคำถามว่ากำลังมองหารูปแบบที่ถูกต้องในวงกว้างซึ่งอาจไม่สอดคล้องกันภายใน - ตัวอย่างเช่นมีชุดตัวเลขที่ถูกต้อง แต่ไม่ตรวจสอบว่า trunk-line, exchange, ฯลฯ เป็นรูปแบบที่ถูกต้องสำหรับคำนำหน้ารหัสประเทศ .

อเมริกาเหนือนั้นตรงไปตรงมาและสำหรับชาวต่างชาติฉันชอบที่จะใช้รูปแบบ 'สำนวน' ซึ่งครอบคลุมถึงวิธีที่ผู้คนระบุและจดจำตัวเลขของพวกเขา:

^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$

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

  • (xxx)xxx-xxxx
  • (xxx)-xxx-xxxx
  • (xxx)xxx-xxxx x123
  • 12 1234 123 1 x1111
  • 12 12 12 12 12
  • 12 1 1234 123456 x12345
  • +12 1234 1234
  • +12 12 12 1234
  • +12 1234 5678
  • +12 12345678

สิ่งนี้อาจลำเอียงเนื่องจากประสบการณ์ของฉัน จำกัด เฉพาะอเมริกาเหนือยุโรปและเอเชียเล็กน้อย


ฉันพยายามใช้งานด้านบนในสคริปต์การตรวจสอบความถูกต้องของจาวาสคริปต์ แต่ได้รับinvalid quantifierข้อผิดพลาด มีความคิดเห็นเกี่ยวกับสิ่งที่ฉันทำผิดหรือเปล่า?
แจนิส

ฉันจะเพิ่มกรณีเล็ก ๆ น้อย ๆ ที่มีการระบุโทรศัพท์โดยไม่มีสัญลักษณ์ แต่อาจมีช่องว่างและรหัสประเทศในยุโรปเป็นเรื่องปกติสำหรับหมายเลขท้องถิ่นและมือถือ: 676412342, 676 46 32 12, 676 463 212
rupps

11

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

regex ต่อไปนี้จะจับการรวมกันของตัวเลขและอักขระที่ใช้กันอย่างแพร่หลายในรูปแบบหมายเลขโทรศัพท์ทั่วโลกที่หลากหลาย:

/^\s*(?:\+?(\d{1,3}))?([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/gm

บวก:
+42 555.123.4567
+ 1- (800) -123-4567
+7 555 1234567
7 (926) 1234567
(926) 1234567
79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 123 45 67
89261234567
8 (926) 1234567
926.123.4567
415-555-1234
650-555-2345
(416)555-3456
202 555 4567
4035555678
1 416 555 9292

ติดลบ:
926 3 4
8 800 600 แอปเปิ้ล

แหล่งต้นฉบับ: http://www.regexr.com/38pvb


สิ่งนี้มีการสนับสนุนที่ จำกัด สำหรับส่วนขยาย ตรงกับ "616-555-1234 x567" แต่ไม่ใช่ "616-555-1234 ext. 567"
Jon Schneider

2
ค่าบวกเท็จสำหรับเช่น "------- ((((((55555555" หรือ "9999999999999999999999999")
mikep

มันไม่ได้ตรวจสอบหมายเลข Nitherland macdonalds +31 76 596 4192 (ฉันเพิ่งทดสอบหาตัวเลขสุ่ม)
BIOHAZARD

10

ความรู้สึกของฉันได้รับการเสริมด้วยจำนวนการตอบกลับในหัวข้อนี้ - ว่ามีวิธีแก้ปัญหาที่ไม่มีที่สิ้นสุดสำหรับปัญหานี้ไม่มีที่จะสวยงาม

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

ในความคิดของฉันทางออกที่ดีที่สุดคือการตรวจสอบความยาวขั้นต่ำไม่มีอะไรเพิ่มเติม


หลังจากที่พยายามเป็นจำนวนมากเหล่านี้และจะผ่านข้อมูลที่มีอยู่และข้อเสนอแนะจากผู้ใช้ i จะมีแนวโน้มที่จะเห็นด้วย ...
คริสโตคิง

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

10

นี่เป็นรูปแบบการแสดงออกปกติอย่างง่ายสำหรับหมายเลขโทรศัพท์มือถือของฟิลิปปินส์:

((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

หรือ

((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

จะจับคู่เหล่านี้:

+63.917.123.4567  
+63-917-123-4567  
+63 917 123 4567  
+639171234567  
09171234567  

คนแรกจะตรงกับรหัสประเทศสองหลักใด ๆ ในขณะที่คนที่สองจะตรงกับรหัสประเทศฟิลิปปินส์โดยเฉพาะ

ทดสอบที่นี่: http://refiddle.com/1ox


ขอบคุณ แล้วหมายเลขโทรศัพท์พื้นฐานพร้อมรหัสพื้นที่เช่น 028231234 ฉันสงสัยว่ารหัสพื้นที่เป็นเพียงตัวเลข 2-3 หลักและนำหน้าด้วย 0 เสมอหรือไม่
stormwild

9

นี่คือความพยายามที่ดีที่สุดของฉันจนถึงตอนนี้ มันจัดการรูปแบบด้านบน แต่ฉันแน่ใจว่าฉันพลาดรูปแบบอื่น ๆ ที่เป็นไปได้

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$

9

คุณจะมีช่วงเวลาที่ยากลำบากในการจัดการกับหมายเลขระหว่างประเทศด้วย regex แบบง่าย ๆ ดูโพสต์นี้เกี่ยวกับปัญหาของหมายเลขโทรศัพท์ระหว่างประเทศ (และอเมริกาเหนือ)

คุณต้องการแยกตัวเลขสองหลักแรกเพื่อกำหนดว่ารหัสประเทศคืออะไรจากนั้นทำหน้าที่แตกต่างกันไปตามแต่ละประเทศ

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

คุณระบุอย่างถูกต้องแล้วว่าเป็นปัญหาที่ยุ่งยาก ...

อดัม


ไม่ใช่ทางออกที่นำเสนอ มันเป็นไปได้. เพียงเพราะมันซับซ้อนหรือซับซ้อนไม่ได้หมายความว่าคุณควรโยนแขนขึ้น
Eric Hodonsky

7

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

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

จนถึงตอนนี้มันทำงานกับทุกสิ่งที่พวกเขาโยนไปแล้ว แต่หากเกิดข้อผิดพลาดขึ้นฉันจะอัปเดตคำตอบนี้

regex:

/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/

ฟังก์ชั่น PHP เพื่อแทนที่หมายเลขโทรศัพท์ทั้งหมดด้วยลิงก์: (ในกรณีที่มีใครอยากรู้):

function phoneToTel($number) {
    $return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
    return $return;
}

+1 1234562222222222222222222222นี้แสดงออกปกติจับคู่
Varda Elentári

ทำไมไม่กลับมา?
thexande

ค่าบวกเท็จสำหรับ "99999999999999999999999999999999999999999"
Ben Wheeler

6

ฉันเชื่อว่าหมายเลข :: หมายเลขโทรศัพท์ :: USและRegexp :: Common (โดยเฉพาะแหล่งที่มาของRegexp :: Common :: URI :: RFC2806 ) โมดูล Perl สามารถช่วยได้

คำถามควรระบุในรายละเอียดอีกเล็กน้อยเพื่ออธิบายวัตถุประสงค์ในการตรวจสอบหมายเลข ตัวอย่างเช่น 911 เป็นหมายเลขที่ถูกต้องในสหรัฐอเมริกา แต่ 911x ไม่ได้มีไว้สำหรับค่าใด ๆ ของ x เพื่อให้ บริษัท โทรศัพท์สามารถคำนวณได้เมื่อคุณโทรออกเสร็จแล้ว ปัญหานี้มีหลายรูปแบบ แต่ regex ของคุณไม่ได้ตรวจสอบส่วนรหัสพื้นที่ดังนั้นจึงไม่น่าเป็นห่วง

เช่นเดียวกับการตรวจสอบความถูกต้องของที่อยู่อีเมลแม้ว่าคุณจะมีผลลัพธ์ที่ถูกต้องคุณก็ไม่สามารถรู้ได้ว่ามันถูกมอบหมายให้ใครบางคนจนกว่าคุณจะลอง

หากคุณพยายามที่จะตรวจสอบการป้อนข้อมูลของผู้ใช้ทำไมไม่ปรับมาตรฐานผลลัพธ์และทำกับมัน? หากผู้ใช้ป้อนหมายเลขที่คุณจำไม่ได้ว่าเป็นหมายเลขที่ถูกต้องให้บันทึกเป็นแบบอินพุตหรือตัดอักขระที่ไม่พร้อมใช้งานออก Number :: Phone :: Normalize Perl module อาจเป็นแหล่งของแรงบันดาลใจ


ฉันกำลังจะออกไปบนกิ่งไม้ที่นี่และบอกว่าการอนุญาตให้ 911 เป็นหมายเลขโทรศัพท์อาจเป็นความคิดที่ไม่ดีในแอปพลิเคชันเกือบทั้งหมดของ regex นี้ จับดีแม้ว่า
Nicholas Flynt

4

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

สำหรับการวิเคราะห์เพิ่มเติมคุณสามารถสมัครสมาชิกกับหนึ่งในผู้ให้บริการจำนวนมากที่จะให้คุณเข้าถึงฐานข้อมูลของตัวเลขที่ถูกต้องเช่นเดียวกับบอกคุณว่าพวกเขากำลังโทรศัพท์พื้นฐานหรือโทรศัพท์มือถือตัดการเชื่อมต่อ ฯลฯ ค่าใช้จ่ายเงิน


การตรวจสอบ? 123% $) *% () $ * () # 456 * () * $ # (* (# $ @ 8908) จะตรงกับโซลูชันที่เสนอของคุณ
PlexQ

1
@PlexQ 555-123-1234, 07777777777, 90210, 01/01/1901 - ผู้ใช้มีความคิดสร้างสรรค์ในการชนขยะผ่านการตรวจสอบ ดีกว่าที่จะไม่เสแสร้งคนที่มีข้อมูลแปลก ๆ โดยใช้การตรวจสอบที่เข้มงวดและบอกพวกเขาว่าพวกเขาผิด
ReactiveRaven

4

ทำการแทนที่กับการจัดรูปแบบอักขระจากนั้นตรวจสอบความถูกต้องของโทรศัพท์ที่เหลือ ใน PHP

 $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
 preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );

การทำลาย regexp ที่ซับซ้อนเช่นนี้อาจมีประสิทธิภาพ แต่ง่ายกว่ามาก


3

ฉันพบว่านี่เป็นสิ่งที่น่าสนใจ ฉันไม่ได้ทดสอบ แต่ดูเหมือนว่ามันจะทำงานได้

<?php
/*
string validate_telephone_number (string $number, array $formats)
*/

function validate_telephone_number($number, $formats)
{
$format = trim(ereg_replace("[0-9]", "#", $number));

return (in_array($format, $formats)) ? true : false;
}

/* Usage Examples */

// List of possible formats: You can add new formats or modify the existing ones

$formats = array('###-###-####', '####-###-###',
                 '(###) ###-###', '####-####-####',
                 '##-###-####-####', '####-####', '###-###-###',
                 '#####-###-###', '##########');

$number = '08008-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '123-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1800-1234-5678';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '(800) 555-123';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1234567890';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}
?>

4
ข้อความของคุณดูเหมือนจะระบุว่าคุณไม่ได้เขียนรหัสนี้ คุณช่วยอ้างถึงแหล่งที่มาได้ไหม
Alastair Irvine

bitrepository.com/how-to-validate-a-telephone-number.htmlดูเหมือนจะเป็นแหล่งที่มา
James Paterson

3

คุณน่าจะดีกว่าด้วยการใช้ Masked Input สำหรับสิ่งนี้ ด้วยวิธีนี้ผู้ใช้สามารถป้อนตัวเลขเท่านั้นและคุณสามารถจัดรูปแบบได้ตามที่เห็นสมควร ฉันไม่แน่ใจว่าสิ่งนี้มีไว้สำหรับเว็บแอปพลิเคชันหรือไม่ แต่ถ้ามันมีปลั๊กอิน jQuery คลิกมากที่มีตัวเลือกสำหรับการทำเช่นนี้

http://digitalbush.com/projects/masked-input-plugin/

พวกเขาถึงวิธีปิดบังหมายเลขโทรศัพท์ในการกวดวิชา


3

นี่คืออันที่ทำงานได้ดีใน JavaScript มันอยู่ในสตริงเพราะนั่นเป็นสิ่งที่วิดเจ็ต Dojo คาดหวัง

ตรงกับหมายเลข NANP ของอเมริกาเหนือ 10 หลักพร้อมส่วนขยายเพิ่มเติม ช่องว่าง, ขีดกลางและจุดเป็นตัวคั่นที่ยอมรับได้

"^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$"

3

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

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

\d+ ?\w{0,9} ?\d+
  • 01234467 extension 123456
  • 01234567x123456
  • 01234567890

2

ความชอบของฉันคือการยอมรับว่าการลอกไม่ใช่ตัวเลขและเพียงแค่ยอมรับสิ่งที่ดีที่สุด อาจแน่ใจได้ว่ามีตัวเลขอย่างน้อยสองหลักแม้ว่าจะห้ามบางอย่างเช่นหมายเลขโทรศัพท์ตัวอักษร "ASK-JAKE"

คู่นิพจน์อย่างง่ายของ Perl อาจเป็น:

@f = /(\d+)/g;
tr/0-9//dc;

ใช้กลุ่มแรกเพื่อรวมกลุ่มหลักเข้าด้วยกันซึ่งอาจให้เบาะแสการจัดรูปแบบ ใช้อันที่สองเพื่อโยนตัวเลขที่ไม่ใช่ตัวเลขทั้งหมด

มันเป็นความกังวลหรือไม่ว่าอาจต้องหยุดชั่วคราวและต้องป้อนคีย์เพิ่มเติม หรือบางอย่างเช่น 555-1212 (รอเสียงบี๊บ) 123?


2
    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

ต้องลงท้ายด้วยตัวเลขสามารถเริ่มต้นด้วย (หรือ + หรือตัวเลขและอาจมี + - (หรือ)


2

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

http://ilovenicii.com/?p=87

PHP


<?php
$pattern = "/^(083|086|085|086|087)\d{7}$/";
$phone = "087343266";

if (preg_match($pattern,$phone)) echo "Match";
else echo "Not match";

นอกจากนี้ยังมีโซลูชัน JQuery ในลิงค์นั้น

แก้ไข:

โซลูชั่น jQuery:

    $(function(){
    //original field values
    var field_values = {
            //id        :  value
            'url'       : 'url',
            'yourname'  : 'yourname',
            'email'     : 'email',
            'phone'     : 'phone'
    };

        var url =$("input#url").val();
        var yourname =$("input#yourname").val();
        var email =$("input#email").val();
        var phone =$("input#phone").val();


    //inputfocus
    $('input#url').inputfocus({ value: field_values['url'] });
    $('input#yourname').inputfocus({ value: field_values['yourname'] });
    $('input#email').inputfocus({ value: field_values['email'] }); 
    $('input#phone').inputfocus({ value: field_values['phone'] });



    //reset progress bar
    $('#progress').css('width','0');
    $('#progress_text').html('0% Complete');

    //first_step
    $('form').submit(function(){ return false; });
    $('#submit_first').click(function(){
        //remove classes
        $('#first_step input').removeClass('error').removeClass('valid');

        //ckeck if inputs aren't empty
        var fields = $('#first_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<12 || value==field_values[$(this).attr('id')] ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }
        });        

        if(!error) {
            if( $('#password').val() != $('#cpassword').val() ) {
                    $('#first_step input[type=password]').each(function(){
                        $(this).removeClass('valid').addClass('error');
                        $(this).effect("shake", { times:3 }, 50);
                    });

                    return false;
            } else {   
                //update progress bar
                $('#progress_text').html('33% Complete');
                $('#progress').css('width','113px');

                //slide steps
                $('#first_step').slideUp();
                $('#second_step').slideDown();     
            }               
        } else return false;
    });

    //second section
    $('#submit_second').click(function(){
        //remove classes
        $('#second_step input').removeClass('error').removeClass('valid');

        var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;  
        var fields = $('#second_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }


        function validatePhone(phone) {
        var a = document.getElementById(phone).value;
        var filter = /^[0-9-+]+$/;
            if (filter.test(a)) {
                return true;
            }
            else {
                return false;
            }
        }

        $('#phone').blur(function(e) {
            if (validatePhone('txtPhone')) {
                $('#spnPhoneStatus').html('Valid');
                $('#spnPhoneStatus').css('color', 'green');
            }
            else {
                $('#spnPhoneStatus').html('Invalid');
            $('#spnPhoneStatus').css('color', 'red');
            }
        });

     });

        if(!error) {
                //update progress bar
                $('#progress_text').html('66% Complete');
                $('#progress').css('width','226px');

                //slide steps
                $('#second_step').slideUp();
                $('#fourth_step').slideDown();     
        } else return false;

    });


    $('#submit_second').click(function(){
        //update progress bar
        $('#progress_text').html('100% Complete');
        $('#progress').css('width','339px');

        //prepare the fourth step
        var fields = new Array(
            $('#url').val(),
            $('#yourname').val(),
            $('#email').val(),
            $('#phone').val()

        );
        var tr = $('#fourth_step tr');
        tr.each(function(){
            //alert( fields[$(this).index()] )
            $(this).children('td:nth-child(2)').html(fields[$(this).index()]);
        });

        //slide steps
        $('#third_step').slideUp();
        $('#fourth_step').slideDown();            
    });


    $('#submit_fourth').click(function(){

        url =$("input#url").val();
        yourname =$("input#yourname").val();
        email =$("input#email").val();
        phone =$("input#phone").val();

        //send information to server
        var dataString = 'url='+ url + '&yourname=' + yourname + '&email=' + email + '&phone=' + phone;  



        alert (dataString);//return false;  
            $.ajax({  
                type: "POST",  
                url: "http://clients.socialnetworkingsolutions.com/infobox/contact/",  
                data: "url="+url+"&yourname="+yourname+"&email="+email+'&phone=' + phone,
                cache: false,
                success: function(data) {  
                    console.log("form submitted");
                    alert("success");
                }
                });  
        return false;

   });


    //back button
    $('.back').click(function(){
        var container = $(this).parent('div'),
        previous  = container.prev();

        switch(previous.attr('id')) {
            case 'first_step' : $('#progress_text').html('0% Complete');
                  $('#progress').css('width','0px');
                       break;
            case 'second_step': $('#progress_text').html('33% Complete');
                  $('#progress').css('width','113px');
                       break;

            case 'third_step' : $('#progress_text').html('66% Complete');
                  $('#progress').css('width','226px');
                       break;

        default: break;
    }

    $(container).slideUp();
    $(previous).slideDown();
});


});

แหล่ง

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