ฉันไม่เข้าใจนิพจน์ทั่วไปจริงๆ คุณช่วยอธิบายพวกเขาให้ฉันฟังได้ง่ายๆ หากมีเครื่องมือหรือหนังสือออนไลน์คุณสามารถลิงก์ไปยังพวกเขาได้หรือไม่?
ฉันไม่เข้าใจนิพจน์ทั่วไปจริงๆ คุณช่วยอธิบายพวกเขาให้ฉันฟังได้ง่ายๆ หากมีเครื่องมือหรือหนังสือออนไลน์คุณสามารถลิงก์ไปยังพวกเขาได้หรือไม่?
คำตอบ:
ส่วนที่สำคัญที่สุดคือแนวคิด เมื่อคุณเข้าใจการทำงานของ Building Block แล้วความแตกต่างของจำนวนไวยากรณ์จะมากกว่าภาษาถิ่นเล็กน้อย เลเยอร์ด้านบนของไวยากรณ์เอ็นจินนิพจน์ปกติของคุณคือไวยากรณ์ของภาษาการเขียนโปรแกรมที่คุณใช้ ภาษาเช่น Perl ลบภาวะแทรกซ้อนนี้ส่วนใหญ่ แต่คุณจะต้องคำนึงถึงข้อควรพิจารณาอื่น ๆ หากคุณใช้นิพจน์ปกติในโปรแกรม C
หากคุณคิดว่านิพจน์ทั่วไปเป็นหน่วยการสร้างที่คุณสามารถผสมและจับคู่ตามที่คุณต้องการมันจะช่วยให้คุณเรียนรู้วิธีการเขียนและดีบักรูปแบบของคุณเอง แต่ยังเข้าใจวิธีรูปแบบที่ผู้อื่นเขียน
แนวคิดการแสดงผลปกติที่ง่ายที่สุดคือตัวอักษร รูปแบบN
ตรงกับอักขระ 'N'
นิพจน์ปกติถัดจากลำดับการจับคู่ซึ่งกันและกัน ตัวอย่างเช่นรูปแบบที่Nick
ตรงกับลำดับ 'N' ตามด้วย 'i' ตามด้วย 'c' ตามด้วย 'k'
หากคุณเคยใช้grep
กับ Unix - เพียงเพื่อค้นหาสตริงการค้นหาทั่วไป - คุณใช้นิพจน์ปกติอยู่แล้ว! ( re
ในgrep
หมายถึงนิพจน์ทั่วไป)
เพิ่มความซับซ้อนเพียงเล็ก ๆ น้อย ๆ ที่คุณสามารถตรงกับทั้ง 'นิค' หรือ 'นิค' [Nn]ick
กับรูปแบบ ส่วนในวงเล็บเหลี่ยมเป็นคลาสอักขระซึ่งหมายความว่าตรงกับหนึ่งในอักขระที่ล้อมรอบ นอกจากนี้คุณยังสามารถใช้ช่วงในคลาสของตัวละครดังนั้น[a-c]
ตรงกับ 'a' หรือ 'b' หรือ 'c'
รูปแบบ.
พิเศษ: มากกว่าตรงกับจุดที่แท้จริงเท่านั้นมันตรงกับใด ๆของตัวละคร† [-.?+%$A-Za-z0-9...]
มันเป็นแนวคิดเดียวกับตัวอักษรระดับใหญ่จริงๆ
นึกถึงคลาสของตัวละครเป็นเมนู: เลือกเพียงอันเดียว
การใช้.
ช่วยให้คุณประหยัดการพิมพ์จำนวนมากและมีทางลัดอื่น ๆ สำหรับรูปแบบทั่วไป สมมติว่าคุณต้องการจับคู่ตัวเลข: วิธีหนึ่งในการเขียนนั่นคือ[0-9]
วิธีหนึ่งที่จะเขียนว่าเป็น ตัวเลขเป็นเป้าหมายการจับคู่บ่อยๆดังนั้นคุณสามารถใช้ทางลัดแทน\d
ได้ ส่วนอื่น ๆ คือ\s
(ช่องว่าง) และ\w
(ตัวอักษรคำ: ตัวอักษรและตัวเลขหรือขีดล่าง)
ตัวแปรที่เป็นตัวพิมพ์ใหญ่เป็นการเติมเต็มดังนั้น \S
จับคู่กับอักขระที่ไม่ใช่สีขาวใด ๆตัวอย่างเช่น
จากนั้นคุณสามารถทำซ้ำส่วนของรูปแบบของคุณกับปริมาณ ตัวอย่างเช่นรูปแบบab?c
ตรงกับ 'abc' หรือ 'ac' เนื่องจาก?
ตัวขยายทำให้รูปแบบย่อยมีการแก้ไขทางเลือก ปริมาณอื่น ๆ
*
(ศูนย์หรือมากกว่านั้น)+
(หนึ่งครั้งขึ้นไป){n}
( nแน่นอนครั้ง){n,}
(อย่างน้อยnครั้ง){n,m}
(อย่างน้อยnครั้ง แต่ไม่เกินmครั้ง)ใส่บางส่วนของบล็อกเหล่านี้ร่วมกันแบบ[Nn]*ick
ตรงทั้งหมด
นัดแรกแสดงให้เห็นถึงบทเรียนสำคัญ: *
ประสบความสำเร็จเสมอ!รูปแบบใด ๆ สามารถจับคู่กับศูนย์ครั้ง
ตัวอย่างที่มีประโยชน์อื่น ๆ :
[0-9]+
(และมันเทียบเท่า \d+
) ตรงกับจำนวนเต็มใด ๆ ที่ไม่เป็นลบ\d{4}-\d{2}-\d{2}
ตรงกับวันที่จัดรูปแบบเช่น 2019-01-01ปริมาณปรับเปลี่ยนรูปแบบไปทางซ้ายทันที คุณอาจคาดหวัง0abc+0
เพื่อให้ตรงกับ '0abc0', '0abcabc0' และอื่น ๆ แต่รูปแบบทันทีc
ไปทางซ้ายของบวกปริมาณคือ ซึ่งหมายความว่า0abc+0
ตรงกับ '0abc0', '0abcc0', '0abccc0' และอื่น ๆ
เพื่อให้ตรงกับหนึ่งหรือมากกว่าลำดับของ 'abc' 0(abc)+0
ด้วยศูนย์ที่ปลายการใช้ วงเล็บแสดงรูปแบบย่อยที่สามารถวัดเป็นหน่วยได้ นอกจากนี้ยังเป็นเรื่องธรรมดาสำหรับเอ็นจิ้นนิพจน์ทั่วไปเพื่อบันทึกหรือ "จับ" ส่วนของข้อความอินพุตที่ตรงกับกลุ่มที่วงเล็บ การแตกบิตด้วยวิธีนี้มีความยืดหยุ่นมากกว่าและมีข้อผิดพลาดน้อยกว่าการนับดัชนีและsubstr
สกัดบิตวิธีนี้มีความยืดหยุ่นมากขึ้นและข้อผิดพลาดน้อยกว่าดัชนีนับและ
ก่อนหน้านี้เราเห็นวิธีหนึ่งในการจับคู่ 'Nick' หรือ 'nick' Nick|nick
อีกประการหนึ่งคือมีการสลับกันในขณะที่ โปรดจำไว้ว่าการสลับนั้นรวมทุกอย่างทางด้านซ้ายและทุกอย่างไปทางขวา ใช้การจัดกลุ่มวงเล็บที่จะ จำกัด ขอบเขตของ|
, เช่น(Nick|nick)
,
สำหรับตัวอย่างอื่นคุณสามารถเขียน[a-c]
เป็นa|b|c
แต่ตอนนี้มีแนวโน้มที่จะก่อให้เกิดผลลัพธ์เพราะการใช้งานจำนวนมากถือว่าทางเลือกที่จะมีความยาวมากกว่า 1
แม้ว่าตัวละครบางตัวตรงกับตัวเอง แต่คนอื่น ๆ มีความหมายพิเศษ รูปแบบที่\d+
ไม่ตรงกับทับขวาตามด้วยตัวพิมพ์เล็ก D \\d\+
ตามด้วยเครื่องหมายบวกที่จะได้รับที่เราต้องการใช้ แบ็กสแลชจะลบความหมายพิเศษออกจากอักขระต่อไปนี้
ปริมาณการแสดงออกปกติมีความโลภ ซึ่งหมายความว่าพวกเขาจับคู่ข้อความให้มากที่สุดเท่าที่จะทำได้ในขณะที่ทำให้รูปแบบทั้งหมดตรงกัน
ตัวอย่างเช่นสมมติว่าอินพุตเป็น
"สวัสดี" เธอพูด "คุณสบายดีไหม"
คุณอาจคาดหวังว่า".+"
จะจับคู่เฉพาะ 'สวัสดี' และจะประหลาดใจเมื่อคุณเห็นว่าตรงกับ 'สวัสดี' ตลอดเวลาผ่าน 'คุณ?'
หากต้องการเปลี่ยนจากความโลภเป็นสิ่งที่คุณคิดว่าระมัดระวังให้เพิ่มส่วนพิเศษ?
เข้ากับปริมาณ ตอนนี้คุณเข้าใจแล้วว่า\((.+?)\)
ตัวอย่างจากคำถามของคุณทำงานอย่างไร มันตรงกับลำดับของวงเล็บซ้ายที่แท้จริงตามด้วยอักขระหนึ่งตัวขึ้นไปและถูกยกเลิกด้วยวงเล็บขวา
หากอินพุตของคุณคือ '(123) (456)' การจับภาพแรกจะเป็น '123' ควอนตัมที่ไม่ใช่โลภต้องการอนุญาตให้ส่วนที่เหลือของรูปแบบเริ่มจับคู่โดยเร็วที่สุด
(สำหรับความสับสนของคุณฉันไม่รู้ภาษาถิ่นปกติที่((.+?))
จะทำสิ่งเดียวกันฉันสงสัยว่ามีบางสิ่งบางอย่างหลงหายในการส่งสัญญาณไปที่ไหนสักแห่งระหว่างทาง)
ใช้รูปแบบพิเศษ^
เพื่อจับคู่เฉพาะที่จุดเริ่มต้นของการป้อนข้อมูลของคุณและ$
เพื่อจับคู่เฉพาะในตอนท้าย การทำ "หนังสือ" กับรูปแบบของคุณที่คุณพูดว่า "ฉันรู้ว่ามีอะไรอยู่ข้างหน้าและข้างหลัง แต่ให้ทุกอย่างระหว่างฉัน" เป็นเทคนิคที่มีประโยชน์
สมมติว่าคุณต้องการจับคู่ความคิดเห็นของแบบฟอร์ม
-- This is a comment --
^--\s+(.+)\s+--$
คุณต้องการเขียน
นิพจน์ทั่วไปนั้นวนซ้ำดังนั้นเมื่อคุณเข้าใจกฎพื้นฐานเหล่านี้แล้วคุณสามารถรวมเข้าด้วยกันได้ตามต้องการ
†:ข้อความข้างต้นที่.
ตรงกับตัวละครใด ๆ เป็นการทำให้เข้าใจง่ายสำหรับวัตถุประสงค์การสอนที่ไม่เป็นความจริงอย่างเคร่งครัด Dot จับคู่อักขระใด ๆ ยกเว้นการขึ้นบรรทัดใหม่"\n"
แต่ในทางปฏิบัติคุณไม่ค่อยคาดหวังรูปแบบเช่น.+
การข้ามขอบเขตการขึ้นบรรทัดใหม่ Perl regexes มี/s
สวิตช์และ Java Pattern.DOTALL
ตัวอย่างเช่นเพื่อให้.
ตรงกับตัวละครใด ๆ เลย สำหรับภาษาที่ไม่มีคุณลักษณะดังกล่าวคุณสามารถใช้สิ่งที่ต้องการ[\s\S]
จับคู่ "ช่องว่างใด ๆ หรือช่องว่างที่ไม่ใช่" ในคำอื่น ๆ
a{,m}
ไม่ได้เป็นอย่างน้อยใน Javascript, Perl และ Python