ฉันจะเขียน regex ให้ตรงกับคำเฉพาะได้อย่างไร


21

ฉันพยายามทำให้ regex ทำงาน แต่ฉันไม่สามารถทำสิ่งที่ฉันต้องการได้

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

rocket
RoCKEt
hi Rocket
This is a rocket.
ROCKET's engine

แต่อย่าเปิดใช้งาน ROCKET เมื่อพบในบางอย่าง

Rocketeer
Sprocket

ฉันพยายามทำให้ถูกต้องโดยใช้ตัวสร้าง regex ออนไลน์ แต่ฉันไม่สามารถจับคู่ให้ตรงกัน


1
นี่เป็นหนึ่งในสถานการณ์ [ไม่บ่อยครั้ง] ที่คำถามอาจเหมาะกว่าสำหรับ Stack Overflow ตรวจสอบให้แน่ใจว่าได้ระบุภาษาและ / หรือแพลตฟอร์มเนื่องจากแต่ละภาษามีลักษณะเฉพาะของตนเอง ตัวอย่างเช่น Windows สุทธิและระดับ Regex (โดยปกติจะเป็นอีกวิธีหนึ่ง Stack Overflow ได้รับคำถามแบบปิดหัวข้อนับร้อยจากนักพัฒนาที่เหมาะสำหรับ Super User มากกว่า)
jww

คำตอบ:


14

ฉันแนะนำให้บุ๊กมาร์กการอ้างอิงด่วนของ MSDN ปกติ

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

\W*((?i)rocket(?-i))\W*

สิ่งที่จะทำคือมองหาอักขระศูนย์หรือมากกว่า (*) ที่ไม่ใช่ตัวอักษรและตัวอักษร (\ W) ตามด้วยจรวดที่ไม่มีตัวพิมพ์เล็กและใหญ่ (? i) จรวด (? - i) และตามด้วยอีกศูนย์หรือมากกว่า *) อักขระที่ไม่ใช่ตัวอักษรและตัวเลข (\ W) เครื่องหมายวงเล็บพิเศษรอบคำที่มีการจับคู่จรวดกำหนดการจับคู่ให้กับกลุ่มแยกต่างหาก จรวดคำจะอยู่ในกลุ่มการแข่งขัน 1

UPDATE 1: Matt กล่าวในความคิดเห็นว่า regex นี้จะใช้ในหลาม Python มีไวยากรณ์ที่แตกต่างกันเล็กน้อย เพื่อให้ได้ผลลัพธ์เดียวกันใน python ให้ใช้ regex นี้และส่งผ่านre.IGNORECASEตัวเลือกไปยังcompileหรือmatchฟังก์ชัน

\W*(rocket)\W*

ในRegex101สามารถจำลองได้โดยป้อน "i" ในกล่องข้อความถัดจากอินพุต regex

อัปเดต 2 Ismael ได้กล่าวไว้ว่า regex นั้นค่อนข้างไม่ถูกต้องเนื่องจากอาจตรงกับ "1rocket1" เขาโพสต์ทางออกที่ดีกว่ามากคือ

(?:^|\W)rocket(?:$|\W)


1
การทดสอบกับผู้ทดสอบ regex ออนไลน์ ( ตัวอย่างเช่นregex101.com ) แสดงว่าไม่ถูกต้องและไม่ตรงกับสตริงตัวอย่างที่ฉันป้อน สิ่งนี้มีวัตถุประสงค์เพื่อใช้เป็นส่วนหนึ่งของสคริปต์ไพ ธ อน สิ่งนี้สร้างความแตกต่างในการเขียนอย่างไร?
Kefka

1
ใช่. คุณสามารถดูได้ที่ regex101.com ว่าคุณสามารถเลือก "รสชาติ" regex ที่ด้านบนซ้ายหลามแตกต่างกันเล็กน้อย ฉันจะปรับปรุงคำตอบของฉันด้วยหลามเทียบเท่า
Xaser

1
ขอบคุณ ฉันคิดว่า regexes นั้นเป็นภาษาอิสระ
Kefka

1
พวกเขาควรจะมี แต่มีความแตกต่างเล็กน้อยในการปฏิบัติ
Xaser

2
และการแข่งขัน\W*(rocket)\W* lrocketlมันควรจะ(?:^|\W)(rocket)(?:$|\W)(โดยไม่ต้อง*และคุณต้องตรวจสอบว่ามันตรงกับจุดเริ่มต้นและ / หรือจุดสิ้นสุดของสตริง)
Ismael Miguel

10

ฉันคิดว่า look-aheads นั้น overkill ในกรณีนี้และคุณควรใช้ขอบเขตของคำกับignorecaseตัวเลือก

\brocket\b

ในคำอื่น ๆ ในหลาม:

>>> x="rocket's"
>>> y="rocket1."
>>> c=re.compile(r"\brocket\b",re.I)  # with the ignorecase option
>>> c.findall(y)
[]
>>> c.findall(x)
['rocket']

ในทางเทคนิคกลุ่มที่ไม่มีการจับภาพนั้นไม่มีข้อผิดพลาดอย่างไรก็ตามตัวเลือก / b ให้ผลลัพธ์แบบเดียวกับโซลูชันของ Ismael แต่อาจดูสง่างามกว่าเล็กน้อย
Xaser

1

ด้วยgrepและคุณสามารถใช้sed \<rocket\>ด้วยความgrepที่-iตัวเลือกที่จะทำให้มันเป็นกรณีตาย ( ฉัน gnore กรณี):

grep -i '\<rocket\>'

ฉันไม่ทราบวิธีที่จะทำให้ทุกsedกรณีเล็ก แต่มีวิธีมนุษย์ถ้ำ:

sed -n '/\<[Rr][Oo][Cc][Kk][Ee][Tt]\>/p'

0

ใช้ตัวเลือกค้นหาทั้งคำเท่านั้น

เท่าที่มีเครื่องหมายวรรคตอนคุณไม่สามารถตอบได้จนกว่าคุณจะรู้รสชาติ / รสชาติ

มันเป็นเธรดที่เก่ามากดังนั้นจึงโพสต์สำหรับคนที่อาจต้องการความเห็นในภายหลัง ผู้ที่เริ่มต้นเธรดอาจย้ายไปยังสิ่งอื่น ... ไม่?


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