ย้อนกลับนัดแรกของ Ruby regex


97

ฉันกำลังมองหาวิธีทำการจับคู่ regex กับสตริงใน Ruby และทำให้มันลัดวงจรในนัดแรก

สตริงที่ฉันกำลังประมวลผลนั้นยาวและดูเหมือนว่าวิธีมาตรฐาน ( matchวิธีการ) จะประมวลผลสิ่งทั้งหมดรวบรวมการแข่งขันแต่ละรายการและส่งคืนวัตถุ MatchData ที่มีรายการที่ตรงกันทั้งหมด

match = string.match(/regex/)[0].to_s

คำตอบ:


136

variableName[/regular expression/]คุณอาจจะลอง นี่คือตัวอย่างผลลัพธ์จาก irb:

irb(main):003:0> names = "erik kalle johan anders erik kalle johan anders"
=> "erik kalle johan anders erik kalle johan anders"
irb(main):004:0> names[/kalle/]
=> "kalle"

นี่ไม่ใช่การแข่งขันและส่งคืนผลลัพธ์แรกเบื้องหลังใช่หรือไม่?
Gishu

7
หลังจากการเปรียบเทียบกับสตริงความยาวต่างๆและดูที่แหล่ง C ปรากฎว่า Regex.match ทำการลัดวงจรและพบเฉพาะการจับคู่ครั้งแรกเท่านั้น
Daniel Beardsley

3
เรียบร้อยไม่รู้เกี่ยวกับทางลัดนี้
Pierre

มีเอกสารบางอย่างเกี่ยวกับทางลัดนี้หรือไม่? ฉันค้นหาสูงและต่ำสำหรับสิ่งที่ฉันคิดว่าเป็นงานที่ค่อนข้างง่ายและแก้ไขปัญหาของฉันได้หลังจากพบสิ่งนี้เท่านั้น ขอบคุณ!
dmourati

5
@dmourati คุณสามารถหาคุณลักษณะนี้บันทึกไว้ในString # [] ขอบคุณที่ถามเกี่ยวกับเอกสารเนื่องจากในการอ่านฉันพบcaptureข้อโต้แย้งซึ่งช่วยให้คุณสามารถคืนค่าการจับภาพแทนการจับคู่แบบเต็ม
slothbear

70

คุณสามารถใช้[]: (ซึ่งเหมือนmatch)

"foo+account2@gmail.com"[/\+([^@]+)/, 1] # matches capture group 1, i.e. what is inside ()
# => "account2"
"foo+account2@gmail.com"[/\+([^@]+)/]    # matches capture group 0, i.e. the whole match
# => "+account2"

4
คำตอบที่ดีที่สุด
akostadinov

23

หากมีเพียงการแข่งขันเท่านั้นที่สำคัญคุณสามารถไปด้วยได้

/regexp/ =~ "string"

ไม่ว่าจะด้วยวิธีใดmatchควรส่งคืนเฉพาะ Hit แรกในขณะที่scanค้นหาตลอดทั้งสตริง เพราะฉะนั้นถ้า

matchData = "string string".match(/string/)
matchData[0]    # => "string"
matchData[1]    # => nil - it's the first capture group not a second match

9

ฉันยังไม่แน่ใจว่าฟีเจอร์นี้ยอดเยี่ยมหรือบ้าไปแล้ว แต่ regex ของคุณสามารถกำหนดตัวแปรท้องถิ่น

/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
dollars #=> "3"

(นำมาจากhttp://ruby-doc.org/core-2.1.1/Regexp.html )


คุณสมบัติที่ยอดเยี่ยม! แค่สิ่งที่ฉันต้องการ
RaphaMex

Caveat: ใช้ได้เฉพาะเมื่อregex =~ string", not when string = ~ regex`
Christopher Oezbek

2

นิพจน์ทั่วไป (นิพจน์ทั่วไป) ไม่ใช่อะไรนอกจากสถานะ จำกัด (FSM)

FSM พยายามตอบคำถาม "รัฐนี้เป็นไปได้หรือไม่"

จะพยายามจับคู่รูปแบบต่อไปจนกว่าจะพบการจับคู่ (สำเร็จ) หรือจนกว่าจะสำรวจเส้นทางทั้งหมดและไม่พบการจับคู่ (ความล้มเหลว)

ในความสำเร็จคำถาม "รัฐนี้เป็นไปได้หรือไม่" ได้รับคำตอบว่า "ใช่" ดังนั้นจึงไม่จำเป็นต้องจับคู่เพิ่มเติมและ regex จะส่งกลับ

ดูสิ่งนี้และสิ่งนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้

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

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