พื้นฐานนิพจน์ทั่วไปใน C++

Regular Expression Basics C



พิจารณาประโยคต่อไปนี้ในเครื่องหมายคำพูด:

'นี่คือคนของฉัน'

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







'นี่คือผู้หญิงของฉัน'

มีความต้องการอื่น ๆ อีกมากมายเช่นนี้จากผู้ใช้คอมพิวเตอร์ บางส่วนมีความซับซ้อน Regular Expression ย่อมาจาก regex เป็นหัวข้อของการจัดการปัญหาเหล่านี้โดยคอมพิวเตอร์ C++ มาพร้อมกับไลบรารี่ที่เรียกว่า regex ดังนั้นโปรแกรม C ++ เพื่อจัดการ regex ควรเริ่มต้นด้วย:



#รวม

#รวม

ใช้เนมสเปซ std;

บทความนี้จะอธิบายเกี่ยวกับ Regular Expression Basics ใน C++



เนื้อหาบทความ

พื้นฐานนิพจน์ทั่วไป

Regex

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





จับคู่

การจับคู่กล่าวว่าเกิดขึ้นเมื่อคำหรือวลีที่กำลังค้นหาอยู่ หลังจากจับคู่แล้วสามารถแทนที่ได้ ตัวอย่างเช่น หลังจากที่ผู้ชายอยู่ด้านบน ผู้หญิงก็แทนที่ได้

จับคู่ง่าย

โปรแกรมต่อไปนี้แสดงวิธีจับคู่คำว่า man



#รวม

#รวม

ใช้เนมสเปซ std;

intหลัก()
{

regex reg('ชาย');
ถ้า (regex_search('นี่คือคนของฉัน',ทะเบียน))
ค่าใช้จ่าย<< 'ตรงกัน' <<endl;
อื่น
ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

กลับ 0;
}

ฟังก์ชัน regex_search() คืนค่า true หากมีการจับคู่และคืนค่า false หากไม่มีการจับคู่เกิดขึ้น ในที่นี้ ฟังก์ชันรับอาร์กิวเมนต์สองอาร์กิวเมนต์: อันแรกคือสตริงเป้าหมาย และอันที่สองคืออ็อบเจ็กต์ regex regex เองคือ 'man' ในเครื่องหมายคำพูดคู่ คำสั่งแรกในฟังก์ชัน main() จะสร้างวัตถุ regex Regex เป็นประเภทและ reg เป็นวัตถุ regex เอาต์พุตของโปรแกรมด้านบน 'จับคู่' เนื่องจาก 'man' ปรากฏอยู่ในสตริงเป้าหมาย หากไม่พบ 'man' ในเป้าหมาย regex_search() จะส่งคืนค่าเท็จ และผลลัพธ์จะ 'ไม่ตรงกัน'

ผลลัพธ์ของรหัสต่อไปนี้ไม่ตรงกัน:

regex reg('ชาย');
ถ้า (regex_search('นี่คือฝีมือของฉัน',ทะเบียน))
ค่าใช้จ่าย<< 'ตรงกัน' <<endl;
อื่น
ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

ไม่ตรงกันเพราะไม่พบ regex 'man' ในสตริงเป้าหมายทั้งหมด 'นี่คือการสร้างของฉัน'

ลวดลาย

นิพจน์ทั่วไปที่คนข้างบนนี้ พูดนั้นง่ายมาก Regexes มักจะไม่ง่ายอย่างนั้น นิพจน์ทั่วไปมีอักขระเมตา Metacharacters เป็นอักขระที่มีความหมายพิเศษ metacharacter เป็นอักขระเกี่ยวกับอักขระ อักขระเมตา C++ regex คือ:

^$ .* + ? ( ) [ ] { } |

regex ที่มีหรือไม่มีอักขระเมตาคือรูปแบบ

คลาสตัวละคร

วงเล็บเหลี่ยม

รูปแบบสามารถมีอักขระภายในวงเล็บเหลี่ยมได้ ด้วยเหตุนี้ ตำแหน่งเฉพาะในสตริงเป้าหมายจะตรงกับอักขระในวงเล็บเหลี่ยมใดๆ พิจารณาเป้าหมายต่อไปนี้:

'แมวอยู่ในห้อง'

'ค้างคาวอยู่ในห้อง'

'หนูอยู่ในห้อง'

regex, [cbr]at จะจับคู่ cat ในเป้าหมายแรก มันจะตรงกับค้างคาวในเป้าหมายที่สอง มันจะตรงกับหนูในเป้าหมายที่สาม นั่นเป็นเพราะว่า cat or bat or rat ขึ้นต้นด้วย 'c' หรือ 'b' หรือ 'r' ส่วนรหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:

regex reg('[cbr]ที่');
ถ้า (regex_search('แมวอยู่ในห้อง',ทะเบียน))
ค่าใช้จ่าย<< 'ตรงกัน' <<endl;
ถ้า (regex_search('ค้างคาวอยู่ในห้อง',ทะเบียน))
ค่าใช้จ่าย<< 'ตรงกัน' <<endl;
ถ้า (regex_search('หนูอยู่ในห้อง',ทะเบียน))
ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ผลลัพธ์คือ:

ตรงกัน

ตรงกัน

ตรงกัน

ช่วงของตัวละคร

คลาส [cbr] ในรูปแบบ [cbr] จะจับคู่อักขระที่เป็นไปได้หลายตัวในเป้าหมาย มันจะตรงกับ 'c' หรือ 'b' หรือ 'r' ในเป้าหมาย หากเป้าหมายไม่มี 'c' หรือ 'b' หรือ 'r' ตามด้วย at จะไม่มีการจับคู่

ความเป็นไปได้บางอย่างเช่น 'c' หรือ 'b' หรือ 'r' อยู่ในช่วง ช่วงของตัวเลข 0 ถึง 9 มีความเป็นไปได้ 10 ตัว และรูปแบบสำหรับตัวเลขนั้นคือ [0-9] ช่วงของตัวอักษรพิมพ์เล็ก a ถึง z มีความเป็นไปได้ 26 แบบ และรูปแบบสำหรับสิ่งนั้นคือ [a-z] ช่วงของตัวอักษรพิมพ์ใหญ่ A ถึง Z มีความเป็นไปได้ 26 แบบ และรูปแบบสำหรับสิ่งนั้นคือ [A-Z] – ไม่ใช่ metacharacter อย่างเป็นทางการ แต่ในวงเล็บเหลี่ยม จะระบุช่วง ดังนั้นสิ่งต่อไปนี้จะสร้างการแข่งขัน:

ถ้า (regex_search('ID6id',regex('[0-9]')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

สังเกตว่า regex ถูกสร้างขึ้นเป็นอาร์กิวเมนต์ที่สองอย่างไร การจับคู่เกิดขึ้นระหว่างตัวเลข 6 ในช่วง 0 ถึง 9 และ 6 ในเป้าหมาย ID6id รหัสข้างต้นเทียบเท่ากับ:

ถ้า (regex_search('ID6id',regex('[0123456789]')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

รหัสต่อไปนี้สร้างการจับคู่:

charNS[] = 'ID6iE';

ถ้า (regex_search(NS,regex('[a-z]')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

โปรดทราบว่าอาร์กิวเมนต์แรกในที่นี้คือตัวแปรสตริง ไม่ใช่สตริงตามตัวอักษร การแข่งขันอยู่ระหว่าง 'i' ใน [a-z] และ 'i' ใน ID6iE

อย่าลืมว่าช่วงเป็นคลาส อาจมีข้อความอยู่ทางด้านขวาของช่วงหรือด้านซ้ายของช่วงในรูปแบบ รหัสต่อไปนี้สร้างการจับคู่:

ถ้า (regex_search('ID2id เป็นไอดี',regex('รหัส[0-9]รหัส')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

การแข่งขันอยู่ระหว่าง ID[0-9]id และ ID2id ส่วนที่เหลือของสตริงเป้าหมายคือ ID ที่ไม่ตรงกันในสถานการณ์นี้

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

หมายเหตุ: ยัติภังค์ – เป็น metacharacter เฉพาะในวงเล็บเหลี่ยม ซึ่งระบุช่วง ไม่ใช่อักขระเมตาใน regex นอกวงเล็บเหลี่ยม

การปฏิเสธ

คลาสที่มีช่วงสามารถลบล้างได้ นั่นคือต้องไม่ตรงกับอักขระในชุด (คลาส) ซึ่งระบุด้วย ^ metacharacter ที่จุดเริ่มต้นของรูปแบบคลาส หลังวงเล็บเหลี่ยมเปิด ดังนั้น [^0-9] หมายถึงการจับคู่อักขระในตำแหน่งที่เหมาะสมในเป้าหมาย ซึ่งไม่ใช่อักขระใดๆ ในช่วงนั้น รวม 0 ถึง 9 ดังนั้นรหัสต่อไปนี้จะไม่สร้างการจับคู่:

ถ้า (regex_search('0123456789101112',regex('[^ 0-9]')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

อื่น

ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

ตัวเลขภายในช่วง 0 ถึง 9 สามารถพบได้ในตำแหน่งสตริงเป้าหมาย 0123456789101112,; ดังนั้นจึงไม่มีการจับคู่ - การปฏิเสธ

รหัสต่อไปนี้สร้างการจับคู่:

ถ้า (regex_search('ABCDEFGHIJ',regex('[^ 0-9]')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ไม่พบตัวเลขในเป้าหมาย ABCDEFGHIJ,; จึงมีการแข่งขัน

[a-z] คือช่วงนอก [^a-z] ดังนั้น [^a-z] จึงเป็นค่าลบของ [a-z]

[A-Z] คือช่วงนอก [^A-Z] ดังนั้น [^A-Z] จึงเป็นค่าลบของ [A-Z]

มีการปฏิเสธอื่น ๆ

ช่องว่างที่ตรงกัน

‘ ’ หรือ หรือ หรือ หรือ f เป็นอักขระเว้นวรรค ในโค้ดต่อไปนี้ regex จะจับคู่ ' ' ในเป้าหมาย:

ถ้า (regex_search('ของบรรทัดหนึ่ง.NSNSจากบรรทัดที่สอง',regex('NS')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

จับคู่อักขระช่องว่าง

รูปแบบหรือคลาสที่ตรงกับอักขระช่องว่างคือ [ f] ในรหัสต่อไปนี้ ' ' ตรงกัน:

ถ้า (regex_search('หนึ่งสอง',regex('[NSNSNSNS] ')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

จับคู่อักขระที่ไม่ใช่ช่องว่าง

รูปแบบหรือคลาสที่จะจับคู่อักขระที่ไม่ใช่ช่องว่างสีขาวคือ [^ f] รหัสต่อไปนี้สร้างการจับคู่เนื่องจากไม่มีช่องว่างในเป้าหมาย:

ถ้า (regex_search('1234abcd',regex('[^ .'NSNSNSNS] ')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ช่วงเวลา (.) ในรูปแบบ

จุด (.) ในรูปแบบจะจับคู่อักขระใดๆ รวมทั้งตัวมันเอง ยกเว้น ในเป้าหมาย การแข่งขันเกิดขึ้นในรหัสต่อไปนี้:

ถ้า (regex_search('1234abcd',regex('.')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ไม่มีผลลัพธ์ที่ตรงกันในโค้ดต่อไปนี้เนื่องจากเป้าหมายคือ

ถ้า (regex_search('NS',regex('.')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

อื่น

ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

หมายเหตุ: ภายในคลาสอักขระที่มีวงเล็บเหลี่ยม จุดนั้นไม่มีความหมายพิเศษ

การจับคู่ซ้ำ

อักขระหรือกลุ่มอักขระสามารถเกิดขึ้นได้มากกว่าหนึ่งครั้งภายในสตริงเป้าหมาย รูปแบบสามารถจับคู่การทำซ้ำนี้ได้ อักขระเมตา ?, *, + และ {} ใช้เพื่อจับคู่การทำซ้ำในเป้าหมาย หาก x เป็นอักขระที่สนใจในสตริงเป้าหมาย อักขระเมตาจะมีความหมายดังต่อไปนี้:

NS*:แปลว่า ตรงกัน'NS' 0หรือมากกว่าครั้ง,ผม.และ.,กี่ครั้งก็ได้

NS+:แปลว่า ตรงกัน'NS' 1หรือมากกว่าครั้ง,ผม.และ.,อย่างน้อยหนึ่งครั้ง

NS? :แปลว่า ตรงกัน'NS' 0หรือ1 เวลา

NS{NS,}:แปลว่า ตรงกัน'NS'อย่างน้อย n ครั้งหรือมากกว่าบันทึกเครื่องหมายจุลภาค

NS{NS} :จับคู่'NS'ตรง n ครั้ง

NS{NS,NS}:จับคู่'NS'อย่างน้อย n ครั้ง,แต่ไม่เกิน m ครั้ง

เมตาคาแรคเตอร์เหล่านี้เรียกว่า ปริมาณ

ภาพประกอบ

*

* ตรงกับอักขระก่อนหน้าหรือกลุ่มก่อนหน้า 0 ครั้งหรือมากกว่า o* ตรงกับ 'o' ใน dog ของสตริงเป้าหมาย นอกจากนี้ยังตรงกับ oo ในหนังสือและการมอง regex, o* จะจับคู่ boooo ใน The animal booooed.. หมายเหตุ: o* จะจับคู่กับ dig โดยที่ 'o' เกิดขึ้นเป็นศูนย์ (หรือมากกว่า) เวลา

+

+ จะจับคู่อักขระก่อนหน้าหรือกลุ่มก่อนหน้า 1 ครั้งขึ้นไป เปรียบเทียบด้วยศูนย์หรือมากกว่าครั้งสำหรับ * ดังนั้น regex, e+ จะจับคู่ 'e' ใน eat โดยที่ 'e' เกิดขึ้นครั้งเดียว e+ ยังจับคู่ ee ในแกะ โดยที่ e เกิดขึ้นมากกว่าหนึ่งครั้ง หมายเหตุ: e+ จะไม่จับคู่กับ dig เพราะใน dig คำว่า 'e' จะไม่เกิดขึ้นอย่างน้อยหนึ่งครั้ง

?

NS ? จับคู่อักขระก่อนหน้าหรือกลุ่มก่อนหน้า 0 หรือ 1 ครั้ง (และไม่เกิน) แล้วอี? จับคู่ dig เพราะ 'e' เกิดขึ้นใน dig, zero time อี? การจับคู่ชุดเนื่องจาก 'e' เกิดขึ้นในชุดหนึ่งครั้ง หมายเหตุ: อี? ยังคงตรงกับแกะ; แม้ว่าจะมีแกะสองตัว มีความแตกต่างกันนิดหน่อยที่นี่ - ดูในภายหลัง

{NS,}

จับคู่อักขระก่อนหน้าหรือกลุ่มก่อนหน้าอย่างน้อย n ครั้งติดต่อกัน ดังนั้น regex, e{2,} จะจับคู่ e สองตัวในเป้าหมาย, แกะ และ e สามตัวในแกะเป้าหมาย e{2,} ไม่ตรงกับชุด เนื่องจากชุดมี 'e' เพียงตัวเดียว

{NS}

ซึ่งตรงกับการทำซ้ำของอักขระก่อนหน้าหรือกลุ่มก่อนหน้าทั้งหมด n ครั้งติดต่อกัน ดังนั้น regex, e{2} จึงจับคู่ e สองตัวในเป้าหมาย, แกะ e{2} ไม่ตรงกับชุดเนื่องจากชุดมี 'e' เพียงตัวเดียว เอาล่ะ e{2} จับคู่ 'e' สองตัวในเป้าหมาย แกะ มีความแตกต่างกันนิดหน่อยที่นี่ - ดูในภายหลัง

{น,ม}

ซึ่งตรงกับการทำซ้ำหลายครั้งติดต่อกันของอักขระก่อนหน้าหรือกลุ่มก่อนหน้า ที่ใดก็ได้ตั้งแต่ n ถึง m รวม ดังนั้น e{1,3} จึงไม่ตรงกับสิ่งใดใน dig ซึ่งไม่มี 'e' โดยจะจับคู่กับตัว e ตัวเดียวในชุด ตัว e สองตัวในแกะ ตัว e สามตัวในขนแกะ และตัว e ตัว ตัว 3 ตัวใน sheeeep มีความแตกต่างกันนิดหน่อยในนัดที่แล้ว – ดูในภายหลัง

การจับคู่สลับ

พิจารณาสตริงเป้าหมายต่อไปนี้ในคอมพิวเตอร์

ฟาร์มมีสุกรหลายขนาด

โปรแกรมเมอร์อาจต้องการทราบว่าเป้าหมายนี้มีแพะ กระต่าย หรือหมูหรือไม่ รหัสจะเป็นดังนี้:

charNS[] = 'ฟาร์มมีหมูหลายขนาด';

ถ้า (regex_search(NS,regex('แพะ | กระต่าย | หมู')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

อื่น

ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

รหัสสร้างการแข่งขัน สังเกตการใช้อักขระสลับ |. มีตัวเลือกสอง สาม สี่ และอื่นๆ C++ จะพยายามจับคู่ทางเลือกแรกคือ goat ที่ตำแหน่งอักขระแต่ละตัวในสตริงเป้าหมาย ถ้าแพะไม่ประสบความสำเร็จ มันก็จะลองทางเลือกต่อไป กระต่าย ถ้ากระต่ายไม่ประสบความสำเร็จ มันก็จะลองทางเลือกต่อไป หมู หากพิกล้มเหลว C++ จะย้ายไปยังตำแหน่งถัดไปในเป้าหมายและเริ่มต้นด้วยทางเลือกแรกอีกครั้ง

ในโค้ดด้านบน หมูถูกจับคู่

การจับคู่เริ่มต้นหรือสิ้นสุด

จุดเริ่มต้น


ถ้า ^ อยู่ที่จุดเริ่มต้นของ regex ดังนั้น regex สามารถจับคู่ข้อความเริ่มต้นของสตริงเป้าหมายได้ ในโค้ดต่อไปนี้ จุดเริ่มต้นของเป้าหมายคือ abc ซึ่งตรงกัน:

ถ้า (regex_search('abc และ def',regex('^ เอบีซี')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ไม่มีการจับคู่เกิดขึ้นในรหัสต่อไปนี้:

ถ้า (regex_search('ใช่ abc และ def',regex('^ เอบีซี')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

อื่น

ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

ที่นี่ abc ไม่ได้อยู่ที่จุดเริ่มต้นของเป้าหมาย

หมายเหตุ: อักขระ circumflex '^' เป็นอักขระเมตาที่จุดเริ่มต้นของ regex ซึ่งตรงกับจุดเริ่มต้นของสตริงเป้าหมาย มันยังคงเป็น metacharacter ที่จุดเริ่มต้นของคลาสอักขระ ซึ่งมันจะลบล้างคลาส

จบ

หาก $ อยู่ที่ส่วนท้ายของ regex ดังนั้น regex สามารถจับคู่ข้อความสิ้นสุดของสตริงเป้าหมายได้ ในโค้ดต่อไปนี้ จุดสิ้นสุดของเป้าหมายคือ xyz ซึ่งตรงกัน:

ถ้า (regex_search('uvw และ xyz',regex('xyz$')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ไม่มีการจับคู่เกิดขึ้นในรหัสต่อไปนี้:

ถ้า (regex_search('uvw และ xyz สุดท้าย',regex('xyz$')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

อื่น

ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

ที่นี่ xyz ไม่ได้อยู่ที่จุดสิ้นสุดของเป้าหมาย

การจัดกลุ่ม

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

'คอนเสิร์ต (นักเปียโน)'

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

'(นักเปียโนเก่ง)'

ในที่นี้ กลุ่มย่อยหรือสตริงย่อยคือ นักเปียโนก็ดี

สตริงย่อยที่มีส่วนร่วม

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

'ห้องสมุดมีชั้นหนังสือที่น่าชื่นชม';

'นี่คือผู้ทำบัญชี';

'ผู้ทำบัญชีทำงานกับชั้นวางหนังสือ';

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

'ชั้นวางหนังสือ|ผู้ทำบัญชี.'

โดยใช้การสลับ

สังเกตว่าหนังสือซึ่งเป็นเรื่องปกติของทั้งสองคำถูกพิมพ์สองครั้งในสองคำในรูปแบบ เพื่อหลีกเลี่ยงการพิมพ์หนังสือสองครั้ง regex ควรเขียนเป็น:

'หนังสือ (ชั้นวาง | ผู้รักษา)'

ที่นี่กลุ่ม, ชั้นวาง | ผู้รักษา ยังคงใช้ metacharacter สำรอง แต่ไม่ใช่สำหรับคำสองคำที่ยาว มันถูกใช้สำหรับส่วนท้ายสองส่วนของคำยาวสองคำ C++ ถือว่ากลุ่มเป็นเอนทิตี ดังนั้น C++ จะมองหาชั้นวางหรือผู้ดูแลที่มาทันทีหลังหนังสือ ผลลัพธ์ของรหัสต่อไปนี้ตรงกัน:

charNS[] = 'ห้องสมุดมีชั้นหนังสือที่น่าชื่นชม';

ถ้า (regex_search(NS,regex('หนังสือ (ชั้นวาง | ผู้รักษา)')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ชั้นวางหนังสือและไม่ใช่ผู้ทำบัญชีได้รับการจับคู่

icase และ multiline regex_constants

ไอเคส

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

ถ้า (regex_search('ข้อเสนอแนะ',regex('ให้อาหาร',regex::ไอเคส)))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

ผลลัพธ์ตรงกัน ดังนั้นฟีดแบ็คที่มีตัวพิมพ์ใหญ่ 'F' จึงจับคู่กับฟีดที่มีตัวพิมพ์เล็ก 'f' regex::icase ได้รับการสร้างอาร์กิวเมนต์ที่สองของตัวสร้าง regex() หากปราศจากสิ่งนั้น คำแถลงจะไม่ก่อให้เกิดการจับคู่

มัลติไลน์

พิจารณารหัสต่อไปนี้:

charNS[] = 'บรรทัด 1NSสาย2NSบรรทัดที่ 3';

ถ้า (regex_search(NS,regex('^. * $')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

อื่น

ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

เอาต์พุตไม่ตรงกัน regex ^.*$ จะจับคู่สตริงเป้าหมายตั้งแต่ต้นจนจบ .* หมายถึงอักขระใดๆ ยกเว้น ศูนย์ครั้งหรือมากกว่า ดังนั้น เนื่องจากอักขระขึ้นบรรทัดใหม่ ( ) ในเป้าหมาย จึงไม่มีการจับคู่

เป้าหมายคือสตริงหลายบรรทัด เพื่อให้ '.' ตรงกับอักขระขึ้นบรรทัดใหม่ ต้องสร้างค่าคงที่ regex::multiline ซึ่งเป็นอาร์กิวเมนต์ที่สองของการสร้าง regex() รหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:

charNS[] = 'บรรทัด 1NSสาย2NSบรรทัดที่ 3';

ถ้า (regex_search(NS,regex('^. * $',regex::มัลติไลน์)))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

อื่น

ค่าใช้จ่าย<< 'ไม่ตรงกัน' <<endl;

จับคู่สตริงเป้าหมายทั้งหมด

เพื่อให้ตรงกับสตริงเป้าหมายทั้งหมด ซึ่งไม่มีอักขระขึ้นบรรทัดใหม่ ( ) คุณสามารถใช้ฟังก์ชัน regex_match() ได้ ฟังก์ชันนี้แตกต่างจาก regex_search() รหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:

charNS[] = 'ที่หนึ่งที่สองที่สาม';

ถ้า (regex_match(NS,regex('.*ที่สอง.*')))

ค่าใช้จ่าย<< 'ตรงกัน' <<endl;

มีการแข่งขันที่นี่ อย่างไรก็ตาม โปรดทราบว่า regex ตรงกับสตริงเป้าหมายทั้งหมด และสตริงเป้าหมายไม่มี ' '

match_results Object

ฟังก์ชัน regex_search() สามารถรับอาร์กิวเมนต์ระหว่างเป้าหมายและอ็อบเจ็กต์ regex อาร์กิวเมนต์นี้เป็นออบเจกต์ match_results สามารถทราบสตริงที่ตรงกันทั้งหมด (บางส่วน) และสตริงย่อยที่ตรงกันได้ ออบเจ็กต์นี้เป็นอาร์เรย์พิเศษพร้อมเมธอด ประเภทอ็อบเจ็กต์ match_results คือ cmatch (สำหรับตัวอักษรสตริง)

รับแมตช์

พิจารณารหัสต่อไปนี้:

charNS[] = 'ผู้หญิงที่คุณกำลังมองหา!';

cmatch m;

ถ้า (regex_search(NS,NS,regex('ว.ม.น')))

ค่าใช้จ่าย<<NS[0] <<endl;

สตริงเป้าหมายมีคำว่าผู้หญิง ผลลัพธ์คือผู้หญิง' ซึ่งสอดคล้องกับ regex, w.m.n. ที่ดัชนีศูนย์ อาร์เรย์พิเศษจะมีคู่ที่ตรงกันเท่านั้น ซึ่งก็คือผู้หญิง

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

cmatch m;

ถ้า (regex_search('หนูแมวค้างคาว!',NS,regex('[bcr]ที่')))

ค่าใช้จ่าย<<NS[0] <<endl;

ค่าใช้จ่าย<<NS[1] <<endl;

ค่าใช้จ่าย<<NS[2] <<endl;

ผลลัพธ์คือหนูจากดัชนีศูนย์ m[1] และ m[2] ว่างเปล่า

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

ถ้า (regex_search('กระต่าย แพะ หมู!',NS,regex('แพะ | กระต่าย | หมู')))

ค่าใช้จ่าย<<NS[0] <<endl;

ค่าใช้จ่าย<<NS[1] <<endl;

ค่าใช้จ่าย<<NS[2] <<endl;

ผลลัพธ์คือกระต่ายจากดัชนีศูนย์ m[1] และ m[2] ว่างเปล่า

การจัดกลุ่ม

เมื่อกลุ่มมีส่วนร่วม รูปแบบที่ตรงกันทั้งหมดจะเข้าสู่เซลล์ศูนย์ของอาร์เรย์พิเศษ พบสตริงย่อยถัดไปในเซลล์ 1; สตริงย่อยต่อไปนี้จะเข้าสู่เซลล์ 2; และอื่นๆ รหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:

ถ้า (regex_search('หนังสือขายดีวันนี้!',NS,regex('หนังสือ ((เซล) (เลอร์))')))

ค่าใช้จ่าย<<NS[0] <<endl;

ค่าใช้จ่าย<<NS[1] <<endl;

ค่าใช้จ่าย<<NS[2] <<endl;

ค่าใช้จ่าย<<NS[3] <<endl;

ผลลัพธ์คือ:

คนขายหนังสือ

ผู้ขาย

เซลล์

อ่าน

โปรดทราบว่ากลุ่ม (ผู้ขาย) มาก่อนกลุ่ม (เซล)

ตำแหน่งของการแข่งขัน

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

cmatch m;

ถ้า (regex_search('หนังสือขายดีวันนี้!',NS,regex('หนังสือ ((เซล) (เลอร์))')))

ค่าใช้จ่าย<<NS[0] << '->' <<NS.ตำแหน่ง(0) <<endl;

ค่าใช้จ่าย<<NS[1] << '->' <<NS.ตำแหน่ง(1) <<endl;

ค่าใช้จ่าย<<NS[2] << '->' <<NS.ตำแหน่ง(2) <<endl;

ค่าใช้จ่าย<<NS[3] << '->' <<NS.ตำแหน่ง(3) <<endl;

สังเกตการใช้คุณสมบัติตำแหน่งโดยมีดัชนีเซลล์เป็นอาร์กิวเมนต์ ผลลัพธ์คือ:

คนขายหนังสือ->5

ผู้ขาย->9

เซลล์->9

อ่าน->12

ค้นหาและแทนที่

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

#รวม

#รวม

#รวม

ใช้เนมสเปซ std;

intหลัก()
{
สตริง str= 'ผู้ชายของฉันมา. มีคนของคุณไปแล้ว';
สตริงใหม่Str=regex_replace(NS,regex('ชาย'), 'ผู้หญิง');
ค่าใช้จ่าย<<ใหม่Str<<endl;

กลับ 0;
}

ฟังก์ชัน regex_replace() ตามที่เขียนไว้ที่นี่ จะแทนที่การจับคู่ทั้งหมด อาร์กิวเมนต์แรกของฟังก์ชันคือเป้าหมาย อาร์กิวเมนต์ที่สองคืออ็อบเจ็กต์ regex และอาร์กิวเมนต์ที่สามคือสตริงการแทนที่ ฟังก์ชันส่งคืนสตริงใหม่ ซึ่งเป็นเป้าหมายแต่มีการแทนที่ ผลลัพธ์คือ:

ผู้หญิงของฉันมาที่นี่ มีผู้หญิงของคุณไป

บทสรุป

นิพจน์ทั่วไปใช้รูปแบบเพื่อจับคู่สตริงย่อยในสตริงลำดับเป้าหมาย รูปแบบมีเมตาคาแรคเตอร์ ฟังก์ชันที่ใช้กันทั่วไปสำหรับนิพจน์ทั่วไป C++ ได้แก่ regex_search(), regex_match() และ regex_replace() regex คือรูปแบบในเครื่องหมายคำพูดคู่ อย่างไรก็ตาม ฟังก์ชันเหล่านี้ใช้อ็อบเจ็กต์ regex เป็นอาร์กิวเมนต์ ไม่ใช่แค่ regex ต้องสร้าง regex เป็นวัตถุ regex ก่อน ฟังก์ชันเหล่านี้จึงจะสามารถใช้งานได้