การสร้างวัตถุ regexp:
การสร้างนิพจน์ปกติสามารถทำได้โดยตรงเช่นอักขระที่ล้อมรอบด้วยสแลช "/" อย่างไรก็ตามในสภาพแวดล้อมที่จำเป็นต้องมีการเปลี่ยนแปลงพารามิเตอร์ตัวสร้าง regexp () เป็นตัวเลือกที่ดีกว่า:
var reg1 =/'/w+'/g;
var reg2 = ใหม่ regexp ('/' // w+/'', 'g');
การเปรียบเทียบวิธีการสร้างสองวิธีพารามิเตอร์แรกใน Regexp คือสตริงปกติที่จะสร้าง ในอีกด้านหนึ่งมันไม่ได้เป็นตัวแทนของปริมาณโดยตรงดังนั้นจึงไม่ได้ปิดล้อมด้วยสแลช "/"; แทนเครื่องหมายใบเสนอราคา "" และสัญลักษณ์หลบหนี "/" จะต้องหลบหลีกสี่ในสตริง
นอกจากนี้ไม่ว่าจะเป็นปริมาณโดยตรงหรือตัวสร้าง regexp () วัตถุ RegeXP ใหม่จะถูกสร้างและกำหนดให้กับตัวแปร
ความเหมือนและความแตกต่างระหว่างการจับคู่ () และ exec ():
การจับคู่และผู้บริหารเป็นวิธีทั่วไปในการจับคู่สตริงสำหรับการแสดงออกปกติ ฟังก์ชั่นที่ใช้โดยทั้งสองมีความคล้ายคลึงกันโดยมีความแตกต่างเล็กน้อย:
1. วิธีใช้
การจับคู่เป็นวิธีการห่อวัตถุที่มีสตริงการใช้งาน: string.match (regexp);
EXEC เป็นวิธีการของวัตถุนิพจน์ทั่วไปการใช้งาน: regexp.exec (สตริง);
2. ผลลัพธ์ที่ส่งคืน
เมื่อ regexp ไม่ได้ตั้งค่าสถานะทั่วโลก "G":
ผลการส่งคืนของทั้งคู่เหมือนกัน นั่นคือเมื่อไม่มีค่าการจับคู่มันจะส่งคืนค่า null และเมื่อมีค่าการจับคู่มันจะส่งคืนอาร์เรย์ (มาอาร์เรย์) อาร์เรย์ [0] เป็นสตริงการจับคู่อาร์เรย์ [1], อาร์เรย์ [2] ... สอดคล้องกับวงเล็บที่ตรงกันในการแสดงออกปกติ ในเวลาเดียวกันอาร์เรย์มีคุณสมบัติสองประการ array.index แสดงถึงตำแหน่งเริ่มต้นของสตริงการจับคู่และ array.input แสดงถึงสตริงที่เรียกคืน
เมื่อ Regexp มีชุด "G" Global Flag:
การจับคู่ส่งคืนอาร์เรย์อาร์เรย์เมื่อมีค่า แต่ละรายการในอาร์เรย์แสดงถึงสตริงทั้งหมดที่ตรงกับดังนั้นจึงไม่มีการจับคู่ย่อยย่อยอีกต่อไป ในเวลานี้อาร์เรย์ไม่มีแอตทริบิวต์ดัชนีและแอตทริบิวต์อินพุต
Exec ไม่แตกต่างจากประสิทธิภาพโดยไม่มีฉลากทั่วโลก "G" อาร์เรย์อาร์เรย์ที่ส่งคืนอาร์เรย์ [0] คือสตริงการจับคู่ปัจจุบันอาร์เรย์ [1] อาร์เรย์ [2] ... เป็นสตริงการจับคู่ปัจจุบัน ในเวลานี้ให้ความสนใจกับคุณสมบัติ LastIndex ของวัตถุ Regexp ซึ่งแสดงถึงตำแหน่งสุดท้ายในตอนท้ายของสตริงการจับคู่ในสตริงต้นฉบับ เมื่อไม่มีผลการจับคู่เพิ่มเติมคุณสมบัติ LastIndex ถูกตั้งค่าเป็น 0 ดังนั้นคุณสามารถใช้ LastIndex Loop เพื่อค้นหาสตริงการจับคู่ทั้งหมด
รองรับวิธีการจับคู่หลายวิธี:
รหัส JS
var teststr = "ตอนนี้ test001 test002"; var re =/test (/d+)/ig; var r = ""; ในขณะที่ (r = re.exec (testStr)) {แจ้งเตือน (r [0] + "" + r [1]); -นอกจากนี้คุณยังสามารถใช้ TestStr.Match (RE) แต่ด้วยวิธีนี้ไม่มีตัวเลือกสำหรับ G และคุณสามารถรับนัดแรกได้เท่านั้น
1. กฎการแสดงออกปกติ
1.1 อักขระปกติ
ตัวอักษรตัวเลขอักขระจีนขีดเส้นใต้และเครื่องหมายวรรคตอนที่ไม่ได้กำหนดไว้โดยเฉพาะในบทต่อไปนี้ทั้งหมดเป็น "อักขระธรรมดา" ทั้งหมด เมื่ออักขระปกติในนิพจน์ตรงกับสตริงมันจะตรงกับอักขระเดียวกันกับมัน
ตัวอย่างที่ 1: เมื่อนิพจน์ "C" เมื่อจับคู่สตริง "ABCDE" ผลลัพธ์ที่ตรงกันคือ: ความสำเร็จ; เนื้อหาที่ตรงกันคือ: "C"; ตำแหน่งการจับคู่คือ: เริ่มต้นที่ 2 และสิ้นสุดที่ 3 (หมายเหตุ: ตัวห้อยเริ่มต้นจาก 0 หรือ 1 ซึ่งอาจแตกต่างกันไปขึ้นอยู่กับภาษาการเขียนโปรแกรมปัจจุบัน)
ตัวอย่างที่ 2: เมื่อนิพจน์ "BCD" เมื่อจับคู่สตริง "ABCDE" ผลลัพธ์การจับคู่คือ: สำเร็จ; เนื้อหาที่ตรงกันคือ: "BCD"; ตำแหน่งการจับคู่คือ: เริ่มต้นที่ 1 และสิ้นสุดที่ 4
1.2 อักขระหลบหนีอย่างง่าย
สำหรับอักขระบางตัวที่ไม่สะดวกในการเขียนใช้วิธีการเพิ่ม "/" ไปที่ด้านหน้า เราคุ้นเคยกับตัวละครเหล่านี้แล้ว
การแสดงออก | เข้ากันได้ |
/r, /n | หมายถึงการคืนรถและการพักสาย |
/t | สัญลักษณ์แท็บ |
- | หมายถึง "/" เอง |
มีเครื่องหมายวรรคตอนอื่น ๆ ที่พิเศษสำหรับใช้ในบทต่อไปนี้ หลังจากเพิ่ม "/" ไปด้านหน้าพวกเขาแสดงสัญลักษณ์ของตัวเอง ตัวอย่างเช่น: ^ และ $ มีความหมายพิเศษ หากคุณต้องการจับคู่อักขระ "^" และ "$" ในสตริงนิพจน์จะต้องเขียนเป็น "/^" และ "/$"
การแสดงออก | เข้ากันได้ |
- | จับคู่ ^ สัญลักษณ์ตัวเอง |
- | จับคู่สัญลักษณ์ $ |
- | จับคู่จุดทศนิยม (.) เอง |
วิธีการจับคู่ของอักขระที่หลบหนีเหล่านี้คล้ายกับ "อักขระปกติ" นอกจากนี้ยังตรงกับตัวละครเดียวกัน
ตัวอย่างที่ 1: เมื่อนิพจน์ "/$ d" เมื่อจับคู่สตริง "ABC $ de" ผลลัพธ์ที่ตรงกันคือ: ความสำเร็จ; เนื้อหาที่ตรงกันคือ: "$ d"; ตำแหน่งการจับคู่คือ: เริ่มต้นที่ 3 และสิ้นสุดที่ 5
1.3 นิพจน์ที่สามารถจับคู่ 'หลายอักขระ'
วิธีการแสดงบางอย่างในนิพจน์ทั่วไปสามารถจับคู่ 'หลายอักขระ' ใด ๆ ตัวอย่างเช่นนิพจน์ "/d" สามารถจับคู่หมายเลขใด ๆ แม้ว่ามันจะสามารถจับคู่อักขระใด ๆ ในตัวมันได้ แต่ก็สามารถเป็นเพียงตัวเดียวไม่ใช่หลายตัว นี่เป็นเหมือนเมื่อเล่นไพ่โป๊กเกอร์กษัตริย์ขนาดใหญ่และขนาดเล็กสามารถแทนที่การ์ดใดก็ได้ แต่พวกเขาสามารถแทนที่การ์ดใบเดียวเท่านั้น
การแสดงออก | เข้ากันได้ |
/d | หมายเลขใด ๆ ใด ๆ หนึ่งใน 0 ~ 9 |
/w | จดหมายหมายเลขหรือขีดล่างนั่นคือหนึ่งใน A ~ Z, A ~ Z, 0 ~ 9, _ |
/s | อักขระช่องว่างใด ๆ รวมถึงช่องว่างแท็บตัวแบ่งหน้า ฯลฯ |
- | จุดทศนิยมสามารถจับคู่อักขระใด ๆ ยกเว้นอักขระใหม่ (/n) |
ตัวอย่างที่ 1: เมื่อนิพจน์ "/d/d" เมื่อจับคู่ "ABC123" ผลลัพธ์การจับคู่คือ: ความสำเร็จ; เนื้อหาที่ตรงกันคือ: "12"; ตำแหน่งที่ตรงกันคือ: เริ่มต้นที่ 3 และสิ้นสุดที่ 5
ตัวอย่างที่ 2: เมื่อนิพจน์ "A./D" เมื่อจับคู่ "AAA100" ผลลัพธ์การจับคู่คือ: ความสำเร็จ; เนื้อหาที่ตรงกันคือ: "AA1"; ตำแหน่งที่ตรงกันคือ: เริ่มต้นที่ 1 และสิ้นสุดที่ 4
1.4 ปรับแต่งนิพจน์ที่สามารถจับคู่ 'หลายอักขระ'
ใช้วงเล็บเหลี่ยม [] เพื่อมีชุดของอักขระที่สามารถจับคู่กับมันได้ หากคุณใช้ [^] เพื่อมีชุดของอักขระคุณสามารถจับคู่อักขระอื่น ๆ นอกเหนือจากอักขระ ในทำนองเดียวกันแม้ว่ามันจะสามารถจับคู่ใดก็ได้ แต่ก็สามารถเป็นได้เพียงหนึ่งเดียวเท่านั้น
การแสดงออก | เข้ากันได้ |
[AB5@] | จับคู่ "A" หรือ "B" หรือ "5" หรือ "@" |
[^abc] | จับคู่ตัวละครใด ๆ นอกเหนือจาก "A", "B", "C" |
[FK] | จับคู่จดหมายใด ๆ ระหว่าง "f" ~ "k" |
[^A-F0-3] | จับคู่อักขระใด ๆ นอกเหนือจาก "A" ~ "F", "0" ~ "3" |
ตัวอย่างที่ 1: เมื่อนิพจน์ "[BCD] [BCD]" ตรงกับ "ABC123" ผลการแข่งขันคือ: ความสำเร็จ; เนื้อหาที่ตรงกันคือ: "BC"; ตำแหน่งที่ตรงกันคือ: เริ่มต้นที่ 1 และสิ้นสุดที่ 3
ตัวอย่างที่ 2: เมื่อนิพจน์ "[^abc]" ตรงกับ "ABC123" ผลการแข่งขันคือ: ความสำเร็จ; เนื้อหาที่ตรงกันคือ: "1"; ตำแหน่งที่ตรงกันคือ: เริ่มต้นที่ 3 และสิ้นสุดที่ 4
1.5 สัญลักษณ์พิเศษที่แก้ไขจำนวนการแข่งขัน
นิพจน์ที่กล่าวถึงในบทก่อนหน้าสามารถจับคู่อักขระหนึ่งตัวหรือตัวละครตัวใดตัวหนึ่งได้ หากคุณใช้นิพจน์รวมถึงสัญลักษณ์พิเศษที่ปรับเปลี่ยนจำนวนการจับคู่คุณสามารถทำซ้ำการจับคู่ได้โดยไม่ต้องเขียนนิพจน์ซ้ำ ๆ
วิธีการใช้งานคือ: "จำนวนการดัดแปลง" ถูกวางไว้หลังจาก "นิพจน์ที่แก้ไข" ตัวอย่างเช่น: "[BCD] [BCD]" สามารถเขียนเป็น "[BCD] {2}"
การแสดงออก | ผล |
{n} | นิพจน์ซ้ำแล้วซ้ำอีก N ตัวอย่างเช่น: "/w {2}" เทียบเท่ากับ "/w/w"; "A {5}" เทียบเท่ากับ "aaaaa" |
{m, n} | การแสดงออกซ้ำแล้วซ้ำอีกครั้ง M และในเวลาส่วนใหญ่ ตัวอย่างเช่น: "ba {1,3}" สามารถจับคู่ "ba" หรือ "baa" หรือ "baaa" |
{m,} | นิพจน์ซ้ำอย่างน้อย m เวลาตัวอย่างเช่น: "/w/d {2,}" สามารถจับคู่ "A12", "_ 456", "M12344" ... |
- | Match Expression 0 หรือ 1 ซึ่งเทียบเท่ากับ {0,1} ตัวอย่างเช่น: "A [cd]?" สามารถจับคู่ "A", "AC", "AD" |
- | นิพจน์ปรากฏขึ้นอย่างน้อยหนึ่งครั้งซึ่งเทียบเท่ากับ {1,} ตัวอย่างเช่น: "A+B" สามารถจับคู่ "AB", "AAB", "AAAB" ... |
- | นิพจน์ไม่ปรากฏหรือเกิดขึ้นได้ตลอดเวลาซึ่งเทียบเท่ากับ {0,} ตัวอย่างเช่น: "/^*b" สามารถจับคู่ "b", "^^^ b" ... |
ตัวอย่างที่ 1: เมื่อนิพจน์ "/d+/.?/d*" จับคู่กับ "ค่าใช้จ่าย $ 12.5" ผลการแข่งขันคือประสบความสำเร็จ; เนื้อหาที่ตรงกันคือ: "12.5"; ตำแหน่งที่ตรงกันคือ: เริ่มต้นที่ 10 และสิ้นสุดที่ 14
ตัวอย่างที่ 2: เมื่อนิพจน์ "Go {2,8} GLE" จับคู่กับ "Ads by goooogle" ผลการแข่งขันคือ: ความสำเร็จ; เนื้อหาที่ตรงกันคือ: "goooooogle"; ตำแหน่งที่ตรงกันคือ: เริ่มต้นที่ 7 และสิ้นสุดที่ 17
1.6 สัญลักษณ์พิเศษอื่น ๆ ที่แสดงถึงความหมายที่เป็นนามธรรม
สัญลักษณ์บางอย่างแสดงถึงความหมายพิเศษของนามธรรมในการแสดงออก:
การแสดงออก | ผล |
- | ตรงกับสถานที่ที่สตริงเริ่มต้นไม่ใช่อักขระใด ๆ |
- | ตรงกับจุดสิ้นสุดของสตริงไม่ตรงกับอักขระใด ๆ |
/B | จับคู่ขอบเขตคำนั่นคือตำแหน่งระหว่างคำและช่องว่างและไม่ตรงกับอักขระใด ๆ |
คำอธิบายข้อความเพิ่มเติมยังคงค่อนข้างเป็นนามธรรมดังนั้นให้ตัวอย่างเพื่อช่วยให้ทุกคนเข้าใจ
ตัวอย่างที่ 1: เมื่อนิพจน์ "^aaa" ตรงกับ "xxx aaa xxx" ผลลัพธ์ที่ตรงกันคือ: ล้มเหลว เพราะ "^" ต้องมีการจับคู่เมื่อสตริงเริ่มต้น "^aaa" สามารถจับคู่ได้ก็ต่อเมื่อ "AAA" อยู่ที่จุดเริ่มต้นของสตริงตัวอย่างเช่น: "AAA XXX XXX"
ตัวอย่างที่ 2: เมื่อนิพจน์ "AAA $" จับคู่กับ "XXX AAA XXX" ผลลัพธ์ที่ตรงกันคือ: ล้มเหลว เนื่องจาก "$" ต้องมีการจับคู่จุดสิ้นสุดของสตริง "AAA $" สามารถจับคู่ได้ก็ต่อเมื่อ "AAA" อยู่ที่ส่วนท้ายของสตริงตัวอย่างเช่น: "XXX XXX AAA"
ตัวอย่างที่ 3: เมื่อนิพจน์ "./b." จับคู่กับ "@@@ abc" ผลการจับคู่คือ: ประสบความสำเร็จ; เนื้อหาที่ตรงกันคือ: "@a"; ตำแหน่งการจับคู่คือ: เริ่มต้นที่ 2 และสิ้นสุดที่ 4
คำอธิบายเพิ่มเติม: "/b" คล้ายกับ "^" และ "$" ซึ่งไม่ตรงกับตัวละครใด ๆ แต่มันต้องการให้มันอยู่ทางด้านซ้ายและขวาของตำแหน่งในผลลัพธ์ที่ตรงกันด้านหนึ่งคือช่วง "/w" และอีกด้านหนึ่งคือช่วงไม่ใช่-/w "
ตัวอย่างที่ 4: เมื่อนิพจน์ "/bend/b" ตรงกับ "วันหยุดสุดสัปดาห์, endfor, end", ผลการจับคู่คือ: ประสบความสำเร็จ; เนื้อหาที่ตรงกันคือ: "end"; ตำแหน่งการจับคู่คือ: เริ่มต้นที่ 15 และสิ้นสุดที่ 18
สัญลักษณ์บางอย่างอาจส่งผลกระทบต่อความสัมพันธ์ระหว่างการแสดงออกของ subexpressions ภายในนิพจน์:
การแสดงออก | ผล |
- | ความสัมพันธ์ "หรือ" ระหว่างการแสดงออกทางด้านซ้ายและขวาตรงกับด้านซ้ายหรือด้านขวา |
- | (1). เมื่อมีการแก้ไขจำนวนการจับคู่การแสดงออกในวงเล็บสามารถแก้ไขได้โดยรวม (2). เมื่อรับผลการจับคู่เนื้อหาที่จับคู่โดยนิพจน์ในวงเล็บสามารถแยกได้แยกกัน |
ตัวอย่างที่ 5: เมื่อนิพจน์ "Tom | Jack" ตรงกับสตริง "ฉันเป็นทอมเขาคือแจ็ค" ผลการจับคู่คือ: ประสบความสำเร็จ; เนื้อหาที่ตรงกันคือ: "ทอม"; ตำแหน่งการจับคู่คือ: เริ่มต้นที่ 4 และสิ้นสุดที่ 7 เมื่อจับคู่ตำแหน่งถัดไปผลลัพธ์การจับคู่คือ: สำเร็จ; เนื้อหาที่ตรงกันคือ: "แจ็ค"; เมื่อตำแหน่งการจับคู่: เริ่มต้นที่ 15 และสิ้นสุดที่ 19
ตัวอย่างที่ 6: นิพจน์ "(go/s*)+" เมื่อจับคู่ "ไปกันเถอะ!" ผลการจับคู่คือ: สำเร็จ; เนื้อหาที่ตรงกันคือ: "Go Go Go Go"; ตำแหน่งการจับคู่คือ: เริ่มต้นที่ 6 และสิ้นสุดที่ 14
ตัวอย่างที่ 7: เมื่อนิพจน์ "¥ (/d+/.?/d*)" ถูกจับคู่กับ "¥ 10.9, ¥ 20.5" ผลการแข่งขันคือ: สำเร็จ; เนื้อหาที่ตรงกันคือ: "¥ 20.5"; ตำแหน่งที่ตรงกันคือ: เริ่มต้นที่ 6 และสิ้นสุดที่ 10 เนื้อหาที่ได้รับช่วงการจับคู่แยกต่างหากคือ: "20.5"
2. กฎขั้นสูงบางอย่างในการแสดงออกปกติ
2.1 ความโลภและไม่ใช่สถานที่ในการแข่งขัน
เมื่อใช้สัญลักษณ์พิเศษที่แก้ไขจำนวนการจับคู่มีวิธีการแสดงหลายวิธีที่เปิดใช้งานนิพจน์เดียวกันเพื่อให้ตรงกับเวลาที่แตกต่างกันเช่น: "{m, n}", "{m,}", "?", "?", "*", "+" จำนวนการจับคู่ที่เฉพาะเจาะจงขึ้นอยู่กับสตริงการจับคู่ นิพจน์นี้ที่มีจำนวนการจับคู่ซ้ำที่ไม่แน่นอนมักจะตรงกับหลายครั้งที่สุดเท่าที่จะทำได้ในระหว่างกระบวนการจับคู่ ตัวอย่างเช่นสำหรับข้อความ "dxxxdxxxd" ต่อไปนี้คือ:
การแสดงออก | จับคู่ผลลัพธ์ |
(d) (/w+) | "/W+" จะจับคู่อักขระทั้งหมดหลังจาก "D" "XXXDXXXD" ตัวแรก " |
(d) (/w+) (d) | "/w+" จะตรงกับอักขระทั้งหมด "XXXDXXX" ระหว่าง "D" และ "สุดท้าย" สุดท้าย แม้ว่า "/w+" ยังสามารถจับคู่ "D" สุดท้ายเพื่อให้การแสดงออกทั้งหมดจับคู่ได้สำเร็จ "/w+" สามารถ "ออกไป" สุดท้าย "D" มันสามารถจับคู่ได้ |
จะเห็นได้ว่าเมื่อ "/w+" ตรงกับมันจะตรงกับตัวละครหลายตัวที่ตรงกับกฎให้มากที่สุด แม้ว่าในตัวอย่างที่สอง แต่ก็ไม่ตรงกับ "D" สุดท้าย แต่ก็เป็นการทำให้การแสดงออกทั้งหมดตรงกับความสำเร็จ ในทำนองเดียวกันการแสดงออกกับ "*" และ "{m, n}" จับคู่ให้มากที่สุดเท่าที่จะทำได้และการแสดงออกกับ "?" ยัง "จับคู่" ให้มากที่สุดเท่าที่จะเป็นไปได้เมื่อพวกเขาสามารถจับคู่หรือไม่ตรงกัน หลักการจับคู่นี้เรียกว่ารูปแบบ "ความโลภ"
โหมดที่ไม่ใช่ Greedy:
เพิ่ม "?" ลงชื่อหลังจากแก้ไขสัญลักษณ์พิเศษของจำนวนการแข่งขันสามารถสร้างนิพจน์ด้วยจำนวนการจับคู่ที่แตกต่างกันมากที่สุดเท่าที่จะเป็นไปได้ดังนั้นการแสดงออกที่สามารถจับคู่หรือไม่ตรงกันสามารถ "จับคู่" ให้มากที่สุด หลักการจับคู่นี้เรียกว่ารูปแบบ "non-greedy" หรือที่เรียกว่ารูปแบบ "Barb" หากมีการแข่งขันไม่กี่ครั้งมันจะทำให้นิพจน์ทั้งหมดล้มเหลว เช่นเดียวกับโหมดโลภโหมดที่ไม่ใช่ Greedy จะตรงกับขอบเขตขั้นต่ำเพื่อให้การแสดงออกทั้งหมดตรงกัน ตัวอย่างเช่นสำหรับข้อความ "dxxxdxxxd":
การแสดงออก | จับคู่ผลลัพธ์ |
(d) (/w+?) | "/w+?" จะตรงกับอักขระไม่กี่ตัวหลังจาก "D" ครั้งแรกที่เป็นไปได้และผลลัพธ์คือ: "/w+?" ตรงกับหนึ่ง "x" |
(d) (/w+?) (D) | เพื่อให้นิพจน์ทั้งหมดจับคู่ได้สำเร็จ "/w+?" ต้องจับคู่ "xxx" เพื่อให้การแข่งขัน "D" ที่ตามมาในภายหลังเพื่อให้นิพจน์ทั้งหมดเข้ากันได้สำเร็จ ผลลัพธ์คือ: "/w+?" จับคู่ "xxx" |
สำหรับกรณีเพิ่มเติมโปรดดูสิ่งต่อไปนี้:
ตัวอย่างที่ 1: เมื่อนิพจน์ "<td> (.*) </td>" ตรงกับสตริง "<td> <p> aa </p> </td> <td> <p> bb </p> </td>" ผลการจับคู่คือ: ประสบความสำเร็จ; การจับคู่คือ "<td> <p> aa </p> </td>" สตริงทั้งหมดและ "</td>" ในนิพจน์จะตรงกับ "</td> สุดท้ายในสตริง
ตัวอย่างที่ 2: ในทางตรงกันข้ามเมื่อนิพจน์ "<td> (.*?) </td>" ตรงกับสตริงเดียวกันในตัวอย่างที่ 1 คุณจะได้รับ "<td> <p> aa </p> </td>" เมื่อคุณจับคู่อันถัดไปอีกครั้งคุณจะได้รับครั้งที่สอง "<td> <p> bb </p> </td>"
2.2 backreferences /1, /2 ...
เมื่อนิพจน์ตรงกับ Expression Engine จะบันทึกสตริงที่ตรงกับนิพจน์ที่มีอยู่ในตัวยึด "()" เมื่อได้รับผลลัพธ์การจับคู่สตริงที่ตรงกับนิพจน์ที่มีอยู่ในวงเล็บสามารถรับได้แยกกัน สิ่งนี้แสดงให้เห็นหลายครั้งในตัวอย่างก่อนหน้านี้ ในแอปพลิเคชันที่ใช้งานได้จริงเมื่อใช้ขอบเขตที่แน่นอนในการค้นหาและเนื้อหาที่จะเรียกคืนไม่มีขอบเขตต้องใช้วงเล็บเพื่อระบุช่วงที่ต้องการ ตัวอย่างเช่นก่อนหน้า "<td> (.*?) </td>"
ในความเป็นจริง "สตริงที่ตรงกับนิพจน์ที่มีอยู่ในวงเล็บ" ไม่เพียง แต่สามารถใช้งานได้หลังจากการแข่งขันสิ้นสุดลง แต่ยังอยู่ในระหว่างกระบวนการจับคู่ ชิ้นส่วนหลังจากนิพจน์สามารถอ้างถึง "สตริงการจับคู่ย่อยก่อนหน้านี้ที่จับคู่" ในวงเล็บ วิธีการอ้างอิงคือการเพิ่มตัวเลข "/" "/1" หมายถึงสตริงที่ตรงกับคู่แรกของวงเล็บ "/2" หมายถึงสตริงที่จับคู่ในวงเล็บคู่ที่สอง ... และอื่น ๆ ถ้าวงเล็บคู่หนึ่งมีวงเล็บคู่หนึ่งวงเล็บด้านนอกจะถูกจัดเรียงก่อน กล่าวอีกนัยหนึ่งถ้าทั้งคู่มีตัวยึดซ้าย "(" ก่อนหน้านี้คู่จะถูกจัดเรียงก่อน
เป็นตัวอย่าง:
ตัวอย่างที่ 1: นิพจน์ "('|") (.*?) (/1) "เมื่อจับคู่"' สวัสดี ', "โลก" "ผลการแข่งขันคือ: ประสบความสำเร็จเนื้อหาที่ตรงกันคือ:" สวัสดี' "เมื่อจับคู่อีกครั้งคุณสามารถจับคู่" "โลก" "
ตัวอย่างที่ 2: เมื่อนิพจน์ "(/w)/1 {4,}" ถูกจับคู่กับ "AA BBBB ABCDEFG CCCCC 111121111 99999999999" ผลการแข่งขันคือ: ประสบความสำเร็จ; เนื้อหาที่ตรงกันคือ "CCCCCC" เมื่อคุณจับคู่อันต่อไปอีกครั้งคุณจะได้รับ 999999999 นิพจน์นี้ต้องใช้ตัวละครในช่วง "/w" เพื่อทำซ้ำอย่างน้อย 5 ครั้งโดยให้ความสนใจกับความแตกต่างจาก "/w {5,}"
ตัวอย่างที่ 3: นิพจน์ "<(/w+)/s*(/w+(= ('|").*?/4)?/s*)*>.*? <// 1> "จับคู่" <td id =' td1 'สไตล์ = "bgcolor: สีขาว" ประสบความสำเร็จ.
2.3 การค้นหาล่วงหน้าไม่ตรงกัน; ย้อนกลับการค้นหาล่วงหน้าไม่ตรงกัน
ในบทก่อนหน้านี้ฉันได้พูดคุยเกี่ยวกับสัญลักษณ์พิเศษหลายประการที่แสดงถึงความหมายที่เป็นนามธรรม: "^", "$", "/b" พวกเขาทั้งหมดมีสิ่งหนึ่งที่เหมือนกัน: พวกเขาเองไม่ตรงกับตัวละครใด ๆ แต่จะแนบเงื่อนไขกับ "ปลายสองปลายของสตริง" หรือ "slits ระหว่างอักขระ" หลังจากทำความเข้าใจกับแนวคิดนี้ส่วนนี้จะยังคงแนะนำวิธีการเป็นตัวแทนที่ยืดหยุ่นยิ่งขึ้นอีกวิธีหนึ่งซึ่งเพิ่มเงื่อนไขให้กับ "สองปลาย" หรือ "slits"
ส่งต่อ pre-search: "(? = xxxxx)", "(?! xxxxx)"
รูปแบบ: "(? = xxxxx)" ในสตริงการจับคู่เงื่อนไขที่แนบมากับ "slit" หรือ "สองปลาย" คือด้านขวาของช่องว่างจะต้องสามารถจับคู่การแสดงออกของส่วน xxxxx เนื่องจากเป็นเพียงเงื่อนไขเพิ่มเติมเกี่ยวกับช่องว่างนี้จึงไม่ส่งผลกระทบต่อนิพจน์ที่ตามมาเพื่อให้ตรงกับตัวละครอย่างแท้จริงหลังจากช่องว่างนี้ สิ่งนี้คล้ายกับ "/b" ซึ่งไม่ตรงกับตัวละครใด ๆ "/b" เพียงแค่ใช้ตัวละครก่อนและหลังช่องว่างและตัดสินและจะไม่ส่งผลกระทบต่อการแสดงออกที่อยู่เบื้องหลังเพื่อให้ตรงกับอย่างแท้จริง
ตัวอย่างที่ 1: เมื่อนิพจน์ "windows (? = nt | xp)" ตรงกับ "Windows 98, Windows NT, Windows 2000" มันจะตรงกับ "Windows" ใน "Windows NT" และคำอื่น ๆ "Windows" จะไม่ถูกจับคู่
ตัวอย่างที่ 2: นิพจน์ "(/w) ((? =/1/1/1) (/1))+" เมื่อจับคู่สตริง "AAA FFFFFF 999999999" มันจะสามารถจับคู่ 4 ของ 6 "F" และ 7 จาก 9 "9" นิพจน์นี้สามารถอ่านและตีความได้ว่า: การทำซ้ำหมายเลขตัวอักษรและตัวเลขมากกว่า 4 ครั้งจะตรงกับส่วนก่อน 2 หลักสุดท้าย แน่นอนว่าการแสดงออกนี้ไม่สามารถเขียนได้เช่นนี้และจุดประสงค์ที่นี่มีวัตถุประสงค์เพื่อการสาธิต
รูปแบบ: "(?! xxxxx)" ด้านขวาของช่องว่างจะต้องไม่ตรงกับนิพจน์ xxxxx
ตัวอย่างที่ 3: นิพจน์ "((?!/bstop/b).)+" เมื่อจับคู่ "fdjka ljfdl หยุด fjdsla fdj" มันจะถูกจับคู่ตั้งแต่เริ่มต้นไปยังตำแหน่งก่อน "หยุด" หากไม่มี "หยุด" ในสตริงสตริงทั้งหมดจะถูกจับคู่
ตัวอย่างที่ 4: นิพจน์ "ทำ (?!/w)" สามารถจับคู่ "ทำ" ได้เมื่อจับคู่สตริง "เสร็จแล้วทำสุนัข" ในบทความนี้ผลของการใช้ "ทำ" หลังจาก "(?!/w)" และการใช้ "/b" เหมือนกัน
ย้อนกลับการค้นหาล่วงหน้า: "(? <= xxxxx)", "(? <! xxxxx)"
แนวคิดของทั้งสองรูปแบบนี้คล้ายกับการค้นหาล่วงหน้าล่วงหน้า ข้อกำหนดสำหรับการค้นหาล่วงหน้าย้อนกลับคือ: "ด้านซ้าย" ของช่องว่าง ทั้งสองรูปแบบกำหนดให้พวกเขาจะต้องสามารถจับคู่และจะต้องไม่สามารถจับคู่การแสดงออกที่ระบุแทนที่จะตัดสินด้านขวา เช่น "Forward Pre-Search": ทั้งคู่เป็นเงื่อนไขเพิ่มเติมสำหรับช่องว่างที่พวกเขาอยู่และไม่ตรงกับตัวละครใด ๆ
ตัวอย่างที่ 5: นิพจน์ "(? <=/d {4})/d+(? =/d {4})" เมื่อจับคู่ "1234567890123456" หมายเลขกลาง 8 ยกเว้นตัวเลข 4 ตัวแรกและตัวเลข 4 ตัวสุดท้ายจะถูกจับคู่ เนื่องจาก jscript.regexp ไม่รองรับการค้นหาแบบย้อนกลับบทความนี้จึงไม่สามารถแสดงได้ เอ็นจิ้นอื่น ๆ อีกมากมายสามารถรองรับการค้นหาล่วงหน้าแบบย้อนกลับเช่น: java.util.regex แพ็คเกจเหนือ Java 1.4, System.Text.regularexpressions เนมสเปซใน. NET และเครื่องยนต์ปกติที่ง่ายที่สุดและง่ายที่สุดที่แนะนำโดยเว็บไซต์นี้
3. กฎทั่วไปอื่น ๆ
นอกจากนี้ยังมีกฎบางอย่างที่พบได้ทั่วไปในบรรดาเอ็นจิ้นการแสดงออกทั่วไปซึ่งไม่ได้กล่าวถึงในคำอธิบายก่อนหน้านี้
3.1 ในนิพจน์ "/xxx" และ "/uxxxx" สามารถใช้เพื่อแสดงถึงตัวละคร ("x" หมายถึงหมายเลข hexadecimal)
รูปร่าง | ช่วงตัวละคร |
/xxx | อักขระที่มีตัวเลขในช่วง 0 ถึง 255 เช่น: ช่องว่างสามารถแสดงได้ด้วย "/x20" |
/uxxxxx | อักขระใด ๆ สามารถแสดงได้ด้วย "/u" รวมถึงจำนวนเลขฐานสิบหกตัวเลข 4 หลักเช่น "/medium" |
3.2 ในขณะที่นิพจน์ "/s", "/d", "/w", "/b" เป็นตัวแทนของความหมายพิเศษตัวอักษรตัวใหญ่ที่เกี่ยวข้องเป็นตัวแทนของความหมายตรงข้าม
การแสดงออก | เข้ากันได้ |
/s | จับคู่อักขระที่ไม่ใช่ Whitespace ทั้งหมด ("/s" สามารถจับคู่อักขระช่องว่างแต่ละตัว) |
/d | จับคู่อักขระที่ไม่ใช่ตัวเลขทั้งหมด |
/w | จับคู่อักขระทั้งหมดนอกเหนือจากตัวอักษรตัวเลขและขีดล่าง |
/B | จับคู่ขอบเขตที่ไม่ใช่คำนั่นคือช่องว่างของตัวละครเมื่อทั้งสองฝ่ายเป็น "/w" ในด้านซ้ายและขวาไม่ใช่ "/w" ในด้านซ้ายและขวาไม่ใช่ "/w" ในด้านซ้ายและขวาไม่ได้เป็น |
3.3 มีความหมายพิเศษในการแสดงออกและจำเป็นต้องเพิ่ม "/" เพื่อให้ตรงกับบทสรุปของตัวละครของตัวละคร
อักขระ | อธิบาย |
- | ตรงกับตำแหน่งเริ่มต้นของสตริงอินพุต เพื่อให้ตรงกับตัวละคร "^" เองให้ใช้ "/^" |
- | ตรงกับตำแหน่งสิ้นสุดของสตริงอินพุต เพื่อให้ตรงกับตัวละคร "$" ให้ใช้ "/$" |
- | ทำเครื่องหมายตำแหน่งเริ่มต้นและจุดสิ้นสุดของการแสดงออกย่อย ในการจับคู่วงเล็บให้ใช้ "/(" และ "/)" |
- | ใช้นิพจน์ที่กำหนดเองที่สามารถจับคู่ 'หลายอักขระ' ในการจับคู่วงเล็บให้ใช้ "/[" และ "/]" |
- | สัญลักษณ์ที่แก้ไขจำนวนการจับคู่ หากต้องการจับคู่วงเล็บปีกกาให้ใช้ "/{" และ "/}" |
- | จับคู่อักขระใด ๆ ยกเว้นบรรทัดใหม่ (/n) เพื่อให้ตรงกับจุดทศนิยมของตัวเองให้ใช้ "/." |
- | จำนวนการแก้ไขการจับคู่คือ 0 หรือ 1 เพื่อให้ตรงกับ "?" ตัวละครเองใช้ "/?" |
- | จำนวนของการปรับเปลี่ยนการจับคู่อย่างน้อย 1 ครั้ง เพื่อให้ตรงกับตัวละคร "+" เองให้ใช้ "/+" |
- | จำนวนการแก้ไขการจับคู่คือ 0 หรือใด ๆ เพื่อให้ตรงกับตัวละคร "*" ให้ใช้ "/*" |
- | ความสัมพันธ์ "หรือ" ระหว่างการแสดงออกทางด้านซ้ายและขวา จับคู่ "|" ตัวเองโปรดใช้ "/|" |
3.4 subexpression ในวงเล็บ "()" หากคุณต้องการให้ผลลัพธ์การจับคู่ไม่ถูกบันทึกเพื่อการใช้งานในอนาคตคุณสามารถใช้รูปแบบ "(?: xxxxx)"
ตัวอย่างที่ 1: เมื่อนิพจน์ "(?: (/w)/1)+" จับคู่ "A BBCCDD EFG" ผลลัพธ์คือ "BBCCDD" ผลลัพธ์การจับคู่ของวงเล็บ "(? :)" ไม่ได้บันทึกช่วงดังนั้น "(/w)" ใช้เพื่ออ้างอิง
3.5 บทนำเกี่ยวกับการตั้งค่าแอตทริบิวต์การแสดงออกที่ใช้กันทั่วไป: ไม่รู้ชื่อ, SingLeline, Multiline, Global
คุณสมบัติการแสดงออก | อธิบาย |
ไม่รู้ | โดยค่าเริ่มต้นตัวอักษรในนิพจน์จะมีความละเอียดอ่อน กำหนดค่าเป็นไม่รู้ว่าจะไม่รู้สึกตัวเมื่อจับคู่ เอ็นจิ้นนิพจน์บางอย่างขยายแนวคิดของ "กรณี" ไปยังกรณีของช่วง Unicode |
คนโสด | โดยค่าเริ่มต้นจุดทศนิยม "." จับคู่อักขระอื่นนอกเหนือจากการแบ่งบรรทัด (/n) กำหนดค่าเป็น SingLeline เพื่อให้จุดทศนิยมตรงกับอักขระทั้งหมดรวมถึงตัวแบ่งบรรทัด |
พหุคูณ | โดยค่าเริ่มต้นการแสดงออก "^" และ "$" ตรงกับจุดเริ่มต้น①และสิ้นสุด④ตำแหน่งของสตริง ชอบ: ①xxxxxxxx2/n ③xxxxxxxxxx④ กำหนดค่า multiline เพื่อให้การจับคู่ "^" ①และยังสามารถจับคู่ตำแหน่ง③ก่อนที่บรรทัดถัดไปจะเริ่มขึ้นดังนั้นการจับคู่ "$" ④และยังสามารถจับคู่ตำแหน่ง②ก่อนที่จะใหม่และจบลงด้วยบรรทัดเดียว |
ทั่วโลก | ส่วนใหญ่ใช้งานได้เมื่อใช้นิพจน์เพื่อแทนที่และได้รับการกำหนดค่าเป็น Global เพื่อแทนที่การแข่งขันทั้งหมด |
4. เคล็ดลับอื่น ๆ
4.1 หากคุณต้องการเข้าใจว่าเอ็นจิ้นปกติขั้นสูงยังรองรับไวยากรณ์ปกติที่ซับซ้อนโปรดดูเอกสารของเครื่องยนต์ปกติของ DEELX ในเว็บไซต์นี้
4.2 หากคุณต้องการให้นิพจน์ตรงกับสตริงทั้งหมดแทนที่จะค้นหาชิ้นส่วนจากสตริงคุณสามารถใช้ "^" และ "$" ที่จุดเริ่มต้นและจุดสิ้นสุดของนิพจน์ตัวอย่างเช่น: "^/d+$" ต้องการให้สตริงทั้งหมดมีตัวเลขเท่านั้น
4.3 หากเนื้อหาที่จำเป็นในการจับคู่เป็นคำที่สมบูรณ์และไม่ใช่ส่วนหนึ่งของคำแล้วให้ใช้ "/b" ที่จุดเริ่มต้นและจุดสิ้นสุดของนิพจน์ตัวอย่างเช่น: ใช้ "/b(if| ในขณะที่ else THEELSE THESTHEAT
4.4 นิพจน์ไม่ตรงกับสตริงที่ว่างเปล่า มิฉะนั้นการแข่งขันจะประสบความสำเร็จตลอดเวลาและจะไม่มีอะไรตรงกัน ตัวอย่างเช่น: เมื่อคุณกำลังเตรียมที่จะเขียนนิพจน์ที่ตรงกับ "123", "123. ", "123.5", ".5" ฯลฯ จำนวนเต็มจุดทศนิยมและตัวเลขทศนิยมสามารถละเว้นได้ วิธีที่ดีกว่าในการเขียนคือ: "/d+/.?/d*|/./d+"
4.5 อย่าวนซ้ำอย่างไม่สิ้นสุดสำหรับการจับคู่ย่อยที่สามารถจับคู่สตริงที่ว่างเปล่า หากแต่ละส่วนของการแสดงออกของ subexpression ในวงเล็บสามารถจับคู่ 0 ครั้งและวงเล็บโดยรวมสามารถจับคู่เวลาที่ไม่มีที่สิ้นสุดสถานการณ์อาจรุนแรงกว่าที่บทความก่อนหน้านี้กล่าวและกระบวนการจับคู่อาจเป็นวนซ้ำที่ตายแล้ว แม้ว่าเอ็นจิ้นนิพจน์ทั่วไปบางอย่างจะหลีกเลี่ยงการวนซ้ำที่ตายแล้วในสถานการณ์นี้เช่นการแสดงออกปกติของ. NET เราควรพยายามหลีกเลี่ยงสถานการณ์นี้ หากเราพบกับวนซ้ำที่ตายแล้วเมื่อเขียนนิพจน์เราสามารถเริ่มต้นจากมุมมองนี้และค้นหาว่านี่เป็นเหตุผลที่กล่าวถึงในบทความนี้หรือไม่
4.6 เลือกโหมดโลภและโหมดที่ไม่ใช่เการีดอย่างสมเหตุสมผลดูการอภิปรายหัวข้อ
4.7 หรือ "|" ด้านซ้ายและขวาควรตรงกับตัวละครเพียงด้านเดียวเท่านั้นดังนั้นการแสดงออกทั้งสองด้านของ "|" จะไม่แตกต่างกันเนื่องจากตำแหน่งการแลกเปลี่ยน
บทความถัดไป ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1. กำหนดนิพจน์ทั่วไป
1) มีสองรูปแบบของการกำหนดนิพจน์ปกติหนึ่งเป็นวิธีธรรมดาและอีกวิธีหนึ่งคือวิธีการสร้าง
2) วิธีปกติ: var reg =/นิพจน์/พารามิเตอร์เพิ่มเติม
นิพจน์: สตริงที่แสดงถึงกฎบางอย่างซึ่งสามารถใช้อักขระพิเศษบางอย่างเพื่อแสดงกฎพิเศษซึ่งจะอธิบายอย่างละเอียดในภายหลัง
พารามิเตอร์เพิ่มเติม: ใช้เพื่อขยายความหมายของนิพจน์ปัจจุบันมีพารามิเตอร์หลักสามตัว:
G: หมายความว่าการจับคู่ทั่วโลกสามารถทำได้
ฉัน: มันหมายถึงการจับคู่ที่ไม่รู้สึกตัว
M: หมายความว่าการจับคู่หลายแถวสามารถทำได้
พารามิเตอร์สามตัวข้างต้นสามารถรวมกันโดยพลการเพื่อแสดงถึงความหมายของสารประกอบและแน่นอนว่าไม่มีการเพิ่มพารามิเตอร์
ตัวอย่าง:
var reg =/a*b/;
var reg =/abc+f/g;
3) วิธีการสร้าง: var reg = ใหม่ regexp ("นิพจน์", "เพิ่มพารามิเตอร์");
ความหมายของ "นิพจน์" และ "พารามิเตอร์เพิ่มเติม" นั้นเหมือนกับวิธีการนิยามด้านบน
ตัวอย่าง:
var reg = ใหม่ regexp ("a*b");
var reg = ใหม่ regexp ("abc+f", "g");
4) ความแตกต่างระหว่างวิธีการทั่วไปและวิธีการสร้าง
นิพจน์ในวิธีปกติจะต้องเป็นสตริงคงที่ในขณะที่นิพจน์ในคอนสตรัคเตอร์อาจเป็นสตริงคงที่หรือตัวแปร JS เช่นพารามิเตอร์นิพจน์ตามอินพุตของผู้ใช้ ฯลฯ :
var reg = ใหม่ regexp (document.forms [0] .exprfiled.value, "g");
2. รูปแบบการแสดงออก
1) รูปแบบการแสดงออกหมายถึงวิธีการแสดงออกและรูปแบบของการแสดงออกนั่นคือวิธีการอธิบาย "นิพจน์" ใน var reg =/นิพจน์/พารามิเตอร์เพิ่มเติม?
2) จากมุมมองที่เป็นมาตรฐานรูปแบบการแสดงออกจะถูกแบ่งออกเป็นรูปแบบที่เรียบง่ายและรูปแบบคอมโพสิต
3) รูปแบบง่าย ๆ : หมายถึงรูปแบบที่แสดงผ่านการรวมกันของอักขระสามัญเช่น
var reg =/abc0d/;
จะเห็นได้ว่ารูปแบบง่าย ๆ สามารถแสดงการแข่งขันที่เฉพาะเจาะจงเท่านั้น
4) รูปแบบสารประกอบ: หมายถึงรูปแบบที่แสดงด้วยตัวละครไวลด์การ์ดตัวอย่างเช่น:
var reg =/a+b?/w/;
+,? และ /w เป็นตัวละครไวด์การ์ดทั้งหมดและแสดงถึงความหมายพิเศษ ดังนั้นรูปแบบคอมโพสิตสามารถแสดงตรรกะนามธรรมได้มากขึ้น
มามุ่งเน้นไปที่ความหมายและการใช้งานของแต่ละไวด์การ์ดในโหมดคอมโพสิต
5) คำอธิบายของอักขระพิเศษในโหมดผสม:
1>/: มันถูกใช้เป็นตัวละครหลบหนีในภาษาการเขียนโปรแกรมหลายภาษา โดยทั่วไป
หาก / สัญลักษณ์ตามด้วยอักขระสามัญ C ดังนั้น / c แสดงถึงความหมายพิเศษ ตัวอย่างเช่น n เดิมแสดงถึงตัวละคร n แต่ /n หมายถึงบรรทัดใหม่
หาก / สัญลักษณ์ตามด้วยอักขระพิเศษ C ดังนั้น / c จะแสดงถึงอักขระธรรมดา c ตัวอย่างเช่น / โดยทั่วไปใช้เป็นอักขระหลบหนี แต่ // ใช้เพื่อปรับแต่งอักขระสามัญ /
การใช้ / ในนิพจน์ปกติของ JavaScript นั้นเหมือนกับด้านบน แต่ในภาษาการเขียนโปรแกรมที่แตกต่างกันตารางอักขระพิเศษอาจแตกต่างกัน
2>^: จับคู่จุดเริ่มต้นของสตริงอินพุต หากเป็นการจับคู่แบบหลายบรรทัดนั่นคือพารามิเตอร์เพิ่มเติมของนิพจน์มี M มันจะถูกจับคู่หลังจากใหม่
ตัวอย่าง:
/^b/จับคู่ b แรกใน "bab bc"
ตัวอย่างที่ 2:
/^b/gm การจับคู่
“ badd b
CDAF
B DSFB”
บรรทัดแรกใน B แรก B, B แรกในบรรทัดที่สาม
3> $: จับคู่จุดสิ้นสุดของการสร้างอักขระอินพุต หากเป็นการจับคู่แบบหลายบรรทัดนั่นคือพารามิเตอร์เพิ่มเติมของนิพจน์ที่มี M มันจะถูกจับคู่ก่อนที่จะใหม่
ตรงกันข้ามกับการใช้งาน ^
ตัวอย่าง: / t $ / จับคู่ t ใน "bat" แต่ไม่ตรงกับ t ใน "ความเกลียด"
ตัวอย่างที่ 2: /t $ /match
“ แท็กที่
ค้างคาว"
t สุดท้ายของบรรทัดแรกและ t ของบรรทัดที่สอง
4>*: จับคู่อักขระก่อนหน้า 0 หรือมากกว่า
ตัวอย่าง: /ab* /ตรงกับ "abbbb" ใน "dddabbbbc" และยังตรงกับ "a" ใน "ddda"
5>+: จับคู่อักขระก่อนหน้า 1 ครั้งขึ้นไป
ตัวอย่าง: / ab+ / จับคู่ "abbbb" ใน "dddabbbbc" แต่ไม่ตรงกับ "ddda"
คล้ายกับการใช้งานของ {1,} ต่อไปนี้ (ต้นแบบ: {n,})
6>?: การใช้งาน? ค่อนข้างพิเศษ โดยทั่วไปแล้วจะใช้เพื่อให้ตรงกับอักขระก่อนหน้า 0 ครั้งหรือ 1 ครั้ง แต่มีการใช้งานพิเศษอีกสองรายการ:
ถ้าติดตามทันที *, +,? และ {} หมายถึงจำนวนการจับคู่ขั้นต่ำของการจับคู่ดั้งเดิมเช่น:
/ ba*/ เดิมจับคู่ "baaaa" ใน "bbbaaaa" แต่/ ba*?/ จับคู่ "b" ใน "bbbaaaa" (เพราะ*หมายถึง 0 หรือมากกว่าที่ตรงกันในขณะที่บวกควรหมายถึงจำนวนการแข่งขันขั้นต่ำนั่นคือ 0 แมทช์)
ในทำนองเดียวกัน: / ba+? / ตรงกับ "ba" ใน "baaaa"
เป็นสัญลักษณ์โครงสร้างไวยากรณ์มันจะถูกใช้ใน pre-assert นั่นคือ x (? = y) และ x (?! = y) ที่จะกล่าวถึงในภายหลัง
7>.: "." ลงชื่อเข้าใช้จุดทศนิยมตรงกับตัวละครตัวเดียวยกเว้นตัวละครใหม่
ตัวละครในมาตรฐานทั้งหมดคืออะไร? โปรดดูที่: ชุดอักขระ
ตัวอย่างเช่น: / ab / จับคู่ "ACB" ใน "ACBAA" แต่ไม่ตรงกับ "ABBB"
8> (x): หมายถึงการจับคู่ X (ไม่หมายถึงอักขระ X หรือหมายถึงอักขระโดยเฉพาะ X หมายถึงสตริง) และการจับคู่จะถูกจดจำ ตามไวยากรณ์ประเภทนี้ () เรียกว่า "การจับพ่อแม่" นั่นคือวงเล็บที่ใช้สำหรับการจับภาพ
การจับคู่จะถูกจดจำเนื่องจากในฟังก์ชั่นที่จัดทำโดยนิพจน์ฟังก์ชั่นบางอย่างส่งคืนอาร์เรย์ที่เก็บสตริงการจับคู่ทั้งหมดเช่นฟังก์ชัน exec ()
โปรดทราบว่าหลักฐานที่จำได้ว่า x in () คือการจับคู่ x
ตัวอย่างที่ 1:
var regx =/a (b) c/;
var rs = regx.exec ("abcddd");
ดังที่เห็นได้จากด้านบน / a (b) c / matches "abc" ใน "abcddd" เนื่องจาก (), B จะบันทึกด้วยดังนั้นเนื้อหาหมายเลขที่ส่งคืนโดย RS คือ:
{abc, b}
ตัวอย่างที่ 2:
var regx =/a (b) c/;
var rs = regx.exec ("acbcddd");
RS ส่งคืน null เนื่องจาก / a (b) c / ไม่ตรงกับ "acbcddd" ดังนั้น b in () จะไม่ถูกบันทึก (แม้ว่าสตริงจะมี B)
9> (?: x): จับคู่ x แต่จำไม่ได้ x () ในรูปแบบนี้เรียกว่า "ผู้ปกครองที่ไม่ได้จับตามอง" นั่นคือวงเล็บสำหรับการไม่จับ
ตัวอย่าง:
var regx =/a (?: b) c/;
var rs = regx.exec ("abcddd");
ดังที่เห็นได้จากด้านบน / a (?: b) c / matches "abc" ใน "abcddd" เพราะ (? :), B จะไม่ถูกบันทึกดังนั้นเนื้อหาหมายเลขที่ส่งคืนโดย RS คือ:
{abc}
10> x (? = y): จับคู่ x เฉพาะในกรณีที่ y จะถูกติดตามทันที หากการจับคู่จับคู่จะมีการจดจำ X เท่านั้นและจะไม่จดจำ y
ตัวอย่าง:
var regx =/user (? = name)/;
var rs = regx.exec ("ชื่อผู้ใช้คือ Mary");
ผลลัพธ์: การจับคู่สำเร็จและค่าของ RS คือ {user}
11> x (?! y): จับคู่ x เฉพาะถ้า y ไม่ได้ติดตามทันที หากการจับคู่จับคู่จะมีการจดจำ X เท่านั้นและจะไม่จดจำ y
ตัวอย่าง:
var regx =/ผู้ใช้ (?! ชื่อ)/;
var rs = regx.exec ("ชื่อผู้ใช้คือ Mary");
ผลลัพธ์: การจับคู่สำเร็จและค่าของ RS คือ {user}
例子2:
var regx=//d+(?!/.)/;
var rs=regx.exec(“54.235”);
Result: The matching result, the value of rs is {5}, and the mismatch is because 54 is followed by the "." เข้าสู่ระบบ. Of course, 235 also matches, but due to the behavior of the exec method, 235 will not be returned.
12>x|y:匹配x或y。注意如果x和y都匹配上了,那么只记住x。
ตัวอย่าง:
var regx=/beijing|shanghai/;
var rs=regx.exec(“I love beijing and shanghai”);
结果:匹配成功,rs的值为{beijing},虽然shanghai也匹配,但不会被记住。
13>{n}:匹配前一个字符的n次出现。
n必须是一个非负数,当然如果是一个负数或小数也不会报语法错误。
ตัวอย่าง:
var regx=/ab{2}c/;
var rs=regx.exec(“abbcd”);
结果:匹配成功,rs的值为:{abbc}。
14>{n,}:匹配前一个字符的至少n次出现。
ตัวอย่าง:
var regx=/ab{2,}c/;
var rs=regx.exec(“abbcdabbbc”);
结果:匹配成功,rs的值为:{abbc}。注意为什么abbbc也符合条件为什么没有被记住,这与exec方法的行为有关,后面会统一讲解。
15>{n,m}:匹配前一个字符的至少n次最多m次的出现。
只要n与m为数字,而且m>=n就不会报语法错误。
ตัวอย่าง:
var regx=/ab{2,5}c/;
var rs=regx.exec(“abbbcd”);
结果:匹配成功,rs的值为:{abbbc}。
例子2:
var regx=/ab{2,2}c/;
var rs=regx.exec(“abbcd”);
结果:匹配成功,rs的值为:{abbc}。
例子3:
var regx=/ab(2,5)/;
var rs=regx.exec(“abbbbbbbbbb”);
Result: The match is successful, and the value of rs is: {abbbbb}, which means that if the previous character appears more than m times, it will only match m times. นอกจากนี้:
var regx=/ab(2,5)c/;
var rs=regx.exec(“abbbbbbbbbbc”);
结果:匹配失败,rs的值为:null,为什么匹配失败,因为b多于5个则b(2,5)会匹配前5个b,,而表达式/ab(2,5)c/中b后面是c,但字符串中5个b之后还是b所以会报错。
16>[xyz]:xyz表示一个字符串,该模式表示匹配[]中的一个字符,形式上[xyz]等同于[xz]。
ตัวอย่าง:
var regx=/a[bc]d/;
var rs=regx.exec(“abddgg”);
结果:匹配成功,rs的值为:{abd}
例子2:
var regx=/a[bc]d/;
var rs=regx.exec(“abcd”);
结果:匹配失败,rs的值为:null,之所以失败,是因为[bc]表示匹配b或c中的一个,但不会同时匹配。
17>[^xyz]:该模式表示匹配非[]中的一个字符,形式上[^xyz]等同于[^xz]。
ตัวอย่าง:
var regx=/a[^bc]d/;
var rs=regx.exec(“afddgg”);
结果:匹配成功,rs的值为:{afd}
例子2:
var regx=/a[^bc]d/;
var rs=regx.exec(“abd”);
结果:匹配失败,rs的值为:。
18>[/b]:匹配退格键。
19>/b:匹配一个词的边界符,例如空格和换行符等等,当然匹配换行符时,表达式应该附加参数m。
ตัวอย่าง:
var regx=//bc./;
var rs=regx.exec(“Beijing is a beautiful city”);
结果:匹配成功,rs的值为:{ci},注意c前边的空格不会匹配到结果中,即{ ci}是不正确的。
20>/B:代表一个非单词边界。
ตัวอย่าง:
var regx=//Bi./;
var rs=regx.exec(“Beijing is a beautiful city”);
结果:匹配成功,rs的值为:{ij},即匹配了Beijing中的ij。
21>/cX,匹配一个控制字符。例如, /cM 匹配一个Control-M 或
回车符。 x 的值必须为AZ 或az 之一。否则,将c 视为一
个原义的'c' 字符。(实际的例子还需补充)
21>/d:匹配一个数字字符,等同于[0-9]。
ตัวอย่าง:
var regx=/user/d/;
var rs=regx.exec(“user1”);
结果:匹配成功,rs的值为:{user1}
22>/D:匹配一个非数字字符,等同于[^0-9]。
ตัวอย่าง:
var regx=/user/D/;
var rs=regx.exec(“userA”);
结果:匹配成功,rs的值为:{userA}
23>/f:匹配一个换页符。
24>/n:匹配一个换行符。因为是换行符,所以在表达式中要加入m参数。
ตัวอย่าง:
var regx=/a/nbc/m;
var str=“a
bc”;
var rs=regx.exec(str);
结果:匹配成功,rs的值为:{ },如果表达式为/a/n/rbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。
25>/r:匹配一个回车符
26>/s:匹配一个空格符,等同于[ /f/n/r/t/v/u00A0/u2028/u2029].
ตัวอย่าง:
var regx=//si/;
var rs=regx.exec(“Beijing is a city”);
结果:匹配成功,rs的值为:{ i}
27>/S:匹配一个非空格符,等同于[ ^/f/n/r/t/v/u00A0/u2028/u2029].
ตัวอย่าง:
var regx=//Si/;
var rs=regx.exec(“Beijing is a city”);
结果:匹配成功,rs的值为:{ei}
28>/t:匹配一个tab
ตัวอย่าง:
var regx=/a/tb/;
var rs=regx.exec(“a bc”);
结果:匹配成功,rs的值为: {a bc}
29>/v:匹配一个竖向的tab
30>/w:匹配一个数字、_或字母表字符,即[A-Za-z0-9_ ]。
ตัวอย่าง:
var regx=//w/;
var rs=regx.exec(“$25.23”);
结果:匹配成功,rs的值为:{2}
31>/W:匹配一个非数字、_或字母表字符,即[^A-Za-z0-9_ ]。
ตัวอย่าง:
var regx=//w/;
var rs=regx.exec(“$25.23”);
结果:匹配成功,rs的值为:{$}
32>/n:注意不是/n,这里n是一个正整数,表示匹配第n个()中的字符。
ตัวอย่าง:
var regx=/user([,-])group/1role/;
var rs=regx.exec(“user-group-role”);
结果:匹配成功,rs的值为:{user-group-role,-},同样对user,group,role的匹配也是成功的,但像user-group,role等就不对了。
33>/0:匹配一个NUL字符。
34>/xhh:匹配一个由两位16进制数字所表达的字符。
35>/uhhhh:匹配一个由四位16进制数字所表达的字符。
3,表达式操作
1)表达式操作,在这里是指和表达式相关的方法,我们将介绍六个方法。
2)表达式对象(RegExp)方法:
1>exec(str),返回str中与表达式相匹配的第一个字符串,而且以数组的形式表现,当然如果表达式中含有捕捉用的小括号,则返回的数组中也可能含有()中的匹配字符串,例如:
var regx=//d+/;
var rs=regx.exec(“3432ddf53”);
返回的rs值为:{3432}
var regx2=new RegExp(“ab(/d+)c”);
var rs2=regx2.exec(“ab234c44”);
返回的rs值为:{ab234c,234}
In addition, if there are multiple suitable matches, exec is executed for the first time and exec is continued, the second and third matches are returned in turn. ตัวอย่างเช่น:
var regx=/user/d/g;
var rs=regx.exec(“ddduser1dsfuser2dd”);
var rs1=regx.exec(“ddduser1dsfuser2dd”);
则rs的值为{user1},rs的值为{rs2},当然注意regx中的g参数是必须的,否则无论exec执行多少次,都返回第一个匹配。后面还有相关内容涉及到对此想象的解释。
2>test(str), determines whether the string str matches the expression, and returns a boolean value. ตัวอย่างเช่น:
var regx=/user/d+/g;
var flag=regx.test(“user12dd”);
flag的值为true。
3)String对象方法
1>match(expr),返回与expr相匹配的一个字符串数组,如果没有加参数g,则返回第一个匹配,加入参数g则返回所有的匹配
ตัวอย่าง:
var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.match(regx);
rs的值为:{user1,user3}
2>search(expr),返回字符串中与expr相匹配的第一个匹配的index值。
ตัวอย่าง:
var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.search(regx);
rs的值为:0
3>replace(expr,str),将字符串中匹配expr的部分替换为str。另外在replace方法中,str中可以含有一种变量符号$,格式为$n,代表匹配中被记住的第n的匹配字符串(注意小括号可以记忆匹配)。
ตัวอย่าง:
var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
rs的值为:003userddd0045
例子2:
var regx=/u(se)r/d/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”$1”);
rs的值为:se3userdddse45
对于replace(expr,str)方法还要特别注意一点,如果expr是一个表达式对象则会进行全局替换(此时表达式必须附加参数g,否则也只是替换第一个匹配),如果expr是一个字符串对象,则只会替换第一个匹配的部分,例如:
var regx=“user”
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
rs的值为: 0013userddduser345
4>split(expr),将字符串以匹配expr的部分做分割,返回一个数组,而且表达式是否附加参数g都没有关系,结果是一样的。
ตัวอย่าง:
var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.split(regx);
rs的值为:{3userddd,45}
4,表达式相关属性
1)表达式相关属性,是指和表达式相关的属性,如下面的形式:
var regx=/myexpr/;
var rs=regx.exec(str);
其中,和表达式自身regx相关的属性有两个,和表达式匹配结果rs相关的属性有三个,下面将逐一介绍。
2)和表达式自身相关的两个属性:
1>lastIndex,返回开始下一个匹配的位置,注意必须是全局匹配(表达式中带有g参数)时,lastIndex才会有不断返回下一个匹配值,否则该值为总是返回第一个下一个匹配位置,例如:
var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex1=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex2=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex3=regx.lastIndex;
上面lastIndex1为9,第二个lastIndex2也为9,第三个也是9;如果regx=/user/d/g,则第一个为9,第二个为18,第三个为0。
2>source, return the expression string itself. ตัวอย่างเช่น:
var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var source=regx.source;
source的值为user/d
3)和匹配结果相关的三个属性:
1>index, return the current matching position. ตัวอย่างเช่น:
var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var index1=rs.index;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index2=rs.index;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index3=rs.index;
index1为4,index2为4,index3为4,如果表达式加入参数g,则index1为4,index2为13,index3会报错(index为空或不是对象)。
2>input, used for matching strings. ตัวอย่างเช่น:
var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var input=rs.input;
input的值为sdsfuser1dfsfuser2。
3>[0],返回匹配结果中的第一个匹配值,对于match而言可能返回一个多值的数字,则除了[0]外,还可以取[1]、[2]等等。例如:
var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var value1=rs[0];
rs=regx.exec(“sdsfuser1dfsfuser2”);
var value2=rs[0];
value1的值为user1,value2的值为user2
5,实际应用
1)实际应用一
描述:有一表单,其中有一个“用户名”input域
要求:汉字,而且不能少于2个汉字,不能多于4个汉字。
ทำให้สำเร็จ:
<script>function checkForm(obj){ var username=obj.username.value; var regx=/^[/u4e00-/u9fa5]{2,4}$/g if(!regx.test(username)){ alert("Invalid username!"); กลับเท็จ; } return true;}</script><form name="myForm" onSubmit="return checkForm(this)"> <input type="text" name="username"/> <input type="submit" vlaue="submit"/>2)实际应用二
描述:给定一个含有html标记的字符串,要求将其中的html标记去掉。
ทำให้สำเร็จ:
<script>function toPlainText(htmlStr){ var regx=/<[^>]*>|<//[^>]*>/gm; var str=htmlStr.replace(regx,""); return str;}</script><form name=“myForm”> <textarea id=“htmlInput”></textarea> <input type=“button” value=“submit” onclick=“toPlainText(document.getElementById('htmlInput').value”/></form>三,小结
1,Javascript正则表达式,我想在一般的程序员之中,使用者应该不是很多,因为我们处理的页面一般都不是很复杂,而复杂的逻辑一般我们都在后台处理完成了。但是目前趋势已经出现了扭转,富客户端已经被越来越多的人接受,而Javascript就是其中的关键技术,对于复杂的客户端逻辑而言,正则表达式的作用也是很关键的,同时它也是Javascript高手必须要掌握的重要技术之一。
2,为了能够便于大家对前面讲述的内容有一个更为综合和深刻的认识,我将前面的一些关键点和容易犯糊涂的地方再系统总结一下,这部分很关键!
总结1:附件参数g的用法
表达式加上参数g之后,表明可以进行全局匹配,注意这里“可以”的含义。我们详细叙述:
1) For the exec method of the expression object, if g is not added, it will only return the first match, no matter how many times it is executed, if g is added, the first execution will also return the first match, and then the execution will return the second match, and so on. ตัวอย่างเช่น
var regx=/user/d/;
var str=“user18dsdfuser2dsfsd”;
var rs=regx.exec(str);//此时rs的值为{user1}
var rs2=regx.exec(str);//此时rs的值依然为{user1}
如果regx=/user/d/g;则rs的值为{user1},rs2的值为{user2}
通过这个例子说明:对于exec方法,表达式加入了g,并不是说执行exec方法就可以返回所有的匹配,而是说加入了g之后,我可以通过某种方式得到所有的匹配,这里的“方式”对于exec而言,就是依次执行这个方法即可。
2)对于表达式对象的test方法,加入g于不加上g没有什么区别。
3) For the match method of the String object, g is not added, and it only returns the first match. If the match method is executed all the time, it always returns the first match. If g is added, then all matches will be returned at once (note that this is different from the exec method of the expression object. For exec, even if g is added, all matches will not be returned at once). ตัวอย่างเช่น:
var regx=/user/d/;
var str=“user1sdfsffuser2dfsdf”;
var rs=str.match(regx);//此时rs的值为{user1}
var rs2=str.match(regx);//此时rs的值依然为{user1}
如果regx=/user/d/g,则rs的值为{user1,user2},rs2的值也为{user1,user2}
4)对于String对象的replace方法,表达式不加入g,则只替换第一个匹配,如果加入g,则替换所有匹配。(开头的三道测试题能很好的说明这一点)
5)对于String对象的split方法,加上g与不加g是一样的,即:
var sep=/user/d/;
var array=“user1dfsfuser2dfsf”.split(sep);
则array的值为{dfsf, dfsf}
此时sep=/user/d/g,返回值是一样的。
6)对于String对象的search方法,加不加g也是一样的。
总结2:附加参数m的用法
附加参数m,表明可以进行多行匹配,但是这个只有当使用^和$模式时才会起作用,在其他的模式中,加不加入m都可以进行多行匹配(其实说多行的字符串也是一个普通字符串),我们举例说明这一点
1)使用^的例子
var regx=/^b./g;var str=“bd76 dfsdf sdfsdfs dffs b76dsf sdfsdf”;var rs=str.match(regx);
此时加入g和不加入g,都只返回第一个匹配{bd},如果regx=/^b./gm,则返回所有的匹配{bd,b7},注意如果regx=/^b./m,则也只返回第一个匹配。所以,加入m表明可以进行多行匹配,加入g表明可以进行全局匹配,综合到一起就是可以进行多行全局匹配
2)使用其他模式的例子,例如
var regx=/user/d/;var str=“sdfsfsdfsdf sdfsuser3 dffs b76dsf user6”;var rs=str.match(regx);
此时不加参数g,则返回{user3},加入参数g返回{user3,user6},加不加入m对此没有影响。
3)因此对于m我们要清楚它的使用,记住它只对^和$模式起作用,在这两种模式中,m的作用为:如果不加入m,则只能在第一行进行匹配,如果加入m则可以在所有的行进行匹配。我们再看一个^的例子
var regx=/^b./;var str=“ret76 dfsdf bjfsdfs dffs b76dsf sdfsdf”;var rs=str.match(regx);
此时rs的值为null,如果加入g,rs的值仍然为null,如果加入m,则rs的值为{bj}(也就是说,在第一行没有找到匹配,因为有参数m,所以可以继续去下面的行去找是否有匹配),如果m和g都加上,则返回{bj,b7}(只加m不加g说明,可以去多行进行匹配,但是找到一个匹配后就返回,加入g表明将多行中所有的匹配返回,当然对于match方法是如此,对于exec呢,则需要执行多次才能依次返回)
总结3:
在HTML的textarea输入域中,按一个Enter键,对应的控制字符为“/r/n”,即“回车换行”,而不是“/n/r”,即“换行回车”,我们看一个前面我们举过的例子:
var regx=/a/r/nbc/;var str=“a bc”;var rs=regx.exec(str);
结果:匹配成功,rs的值为:{ },如果表达式为/a/n/rbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。
The above article briefly discusses the use of RegExp objects and brackets for JS regular expressions is all the content I share with you. ฉันหวังว่ามันจะให้ข้อมูลอ้างอิงและฉันหวังว่าคุณจะสนับสนุน wulin.com มากขึ้น