จับคู่ผลลัพธ์ได้ดีขึ้นด้วย String.prototype.matchAll()

Joe Medley
Joe Medley

Chrome 73 เปิดตัวเมธอด String.prototype.matchAll() ซึ่งทํางานคล้ายกับ match() แต่แสดงผลตัวดำเนินการที่มีนิพจน์ทั่วไปทั้งหมดที่ตรงกันในนิพจน์ทั่วไปส่วนกลางหรือนิพจน์ทั่วไปแบบติดหนึบ วิธีนี้เป็นวิธีที่ง่ายในการวนซ้ำรายการที่ตรงกัน โดยเฉพาะอย่างยิ่งเมื่อคุณต้องการเข้าถึงกลุ่มการจับคู่

match() มีปัญหาอะไร

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

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const results = string.match(regex);
console.log(results);
// → ['test1', 'test2']

เรียกใช้คำสั่งนี้ในคอนโซลและสังเกตว่าระบบแสดงผลอาร์เรย์ที่มีสตริง 'test1' และ 'test2' หากนํา Flag g ออกจากนิพจน์ทั่วไป สิ่งที่ได้จะมีกลุ่มการจับทั้งหมด แต่ฉันจะได้รับการจับคู่รายการแรกเท่านั้น ซึ่งมีลักษณะดังนี้

['test1', 'e', 'st1', '2', index: 0, input: 'test1test2', groups: undefined]

สตริงนี้มีรายการที่ตรงกันครั้งที่ 2 ที่เป็นไปได้ซึ่งขึ้นต้นด้วย 'test2' แต่ฉันไม่มี ทีนี้มาหาคำตอบกัน: ฉันจะรับกลุ่มการจับทั้งหมดสําหรับการจับคู่แต่ละรายการได้อย่างไร คำอธิบายสำหรับข้อเสนอ String.prototype.matchAll() แสดงแนวทางที่เป็นไปได้ 2 วิธี เราจะไม่อธิบายรายละเอียดเนื่องจากหวังว่าคุณจะไม่ต้องใช้ฟีเจอร์เหล่านี้อีกต่อไป

String.prototype.matchAll()

ตัวอย่างคําอธิบายจะมีลักษณะอย่างไรเมื่อใช้ matchAll() ลองดูสิ

const regex = /t(e)(st(\d?))/g;
const string = 'test1test2';
const matches = string.matchAll(regex);
for (const match of matches) {
  console.log(match);
}

สิ่งที่ควรทราบเกี่ยวกับเรื่องนี้มีดังนี้ ซึ่งแตกต่างจาก match() ที่แสดงผลอาร์เรย์ในการค้นหาแบบทั่วไป แต่ matchAll() จะแสดงผลตัวดำเนินการวนซ้ำที่ทำงานร่วมกับลูป for...of ได้อย่างลงตัว ตัวดำเนินการนี้จะสร้างอาร์เรย์สําหรับการจับคู่แต่ละรายการ รวมถึงกลุ่มการจับคู่ที่มีข้อมูลเพิ่มเติมเล็กน้อย หากพิมพ์ข้อมูลเหล่านี้ไปยังคอนโซล ข้อมูลจะมีลักษณะดังนี้

['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', groups: undefined]
['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', groups: undefined]

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

เนื้อหาพิเศษ

ตัวเลือกนี้มีไว้สำหรับผู้ที่เพิ่งเริ่มใช้นิพจน์ทั่วไปหรือไม่ใช่ผู้เชี่ยวชาญ คุณอาจสังเกตเห็นว่าผลลัพธ์ของทั้ง match() และ matchAll() (สําหรับแต่ละรอบ) คืออาร์เรย์ที่มีพร็อพเพอร์ตี้ที่มีชื่อเพิ่มเติม ขณะเตรียมบทความนี้ เราพบว่าพร็อพเพอร์ตี้เหล่านี้มีเอกสารประกอบที่ขาดหายไปบางส่วนใน MDN (ซึ่งเราแก้ไขแล้ว) ต่อไปนี้เป็นคำอธิบายคร่าวๆ

index
ดัชนีของผลลัพธ์แรกในสตริงเดิม ในตัวอย่างข้างต้น test2 เริ่มต้นที่ตําแหน่ง 5 ดังนั้น index จึงมีค่าเป็น 5
input
สตริงแบบสมบูรณ์ที่ matchAll() ทำงานด้วย ในตัวอย่างนี้ 'test1test2'
groups
มีผลการค้นหาของกลุ่มการจับที่มีชื่อที่ระบุไว้ในนิพจน์ทั่วไป

บทสรุป

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