Ruby แทนที่สตริงด้วยรูปแบบ regex ที่จับ


121

ฉันมีปัญหาในการแปลสิ่งนี้เป็น Ruby

นี่คือส่วนหนึ่งของ JavaScript ที่ทำในสิ่งที่ฉันต้องการทำ:

function get_code(str){
    return str.replace(/^(Z_.*): .*/,"$1")​​​​​​​​​​​​​​​​​​​​​​​​​​​;
}

ฉันได้พยายามgsub , ย่อยและแทนที่แต่ไม่มีดูเหมือนจะทำสิ่งที่ผมคาดหวังว่า

นี่คือตัวอย่างของสิ่งที่ฉันได้ลอง:

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/) { |capture| capture }
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "$1")
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "#{$1}")
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\1")
"Z_sdsd: sdsd".gsub(/(.).*/) { |capture| capture }

คุณควรแสดงรหัสจริงสำหรับสิ่งที่คุณได้ลองทำ
อำพัน

@Amber ฉันใส่ตัวอย่างที่ฉันได้ลองแล้ว
JD Isaacks

คำตอบ:


192

ลอง'\1'แทนที่ ( เครื่องหมายคำพูดเดี่ยวมีความสำคัญมิฉะนั้นคุณจะต้องออกจากเครื่องหมาย\):

"foo".gsub(/(o+)/, '\1\1\1')
#=> "foooooo"

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

"foo"[/oo/]
#=> "oo"
"Z_123: foobar"[/^Z_.*(?=:)/]
#=> "Z_123"

68
ทราบว่านี้จะทำงานเฉพาะถ้าสตริงทดแทนอยู่ในราคาเดียว ฉันเสียเวลาไป 5 นาทีเพื่อหาสิ่งนั้น
Vicky Chijwani

7
@MarkThomas - บ่อยครั้งที่เราลองคำตอบยอดนิยม / ได้รับการยอมรับก่อนโดยไม่อ่านคำตอบทั้งหมด โดยทั่วไปแล้วนั่นดูเหมือนจะเป็นวิธีที่มีประสิทธิภาพที่สุดในการแก้ไขปัญหา ให้วิกกี้พัก! :)
Josh M.

@VickyChijwani ความคิดเห็นที่ดี แต่โปรดทราบว่าเมื่อใช้ Ruby inline (ในบรรทัดคำสั่งด้วย-e) มีแนวโน้มที่จะเห็นเครื่องหมายคำพูดคู่ : printf "Punkinhead the name" | ruby -ne 'puts gsub /.*(the name)/, "Jonathans \\1"'เนื่องจากนิพจน์ที่ให้ไว้-eมักจะอยู่ในเครื่องหมายคำพูดเดี่ยว
Jonathan Komar

จะทำอย่างไรกับรูปแบบที่เกิดขึ้นทั้งหมดในสตริง
Jagdeep Singh

1
@JagdeepSingh โดยค่าเริ่มต้นจะแทนที่เหตุการณ์ทั้งหมด
Iulian Onofrei

36

\1ในเครื่องหมายคำพูดคู่จะต้องมีการใช้ Escape คุณต้องการอย่างใดอย่างหนึ่ง

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1")

หรือ

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, '\1')

ดูเอกสารใน gsubที่ระบุว่า "ถ้าเป็นสตริงที่ยกมาสองครั้งการอ้างอิงย้อนกลับทั้งสองจะต้องนำหน้าด้วยแบ็กสแลชเพิ่มเติม"

ดังที่กล่าวไว้หากคุณต้องการเพียงแค่ผลการแข่งขันคุณสามารถทำได้:

"Z_sdsd: sdsd".scan(/^Z_.*(?=:)/)

หรือ

"Z_sdsd: sdsd"[/^Z_.*(?=:)/]

โปรดทราบว่าไฟล์ (?=:)นี้เป็นกลุ่มที่:ไม่ได้จับภาพเพื่อไม่ให้ปรากฏในการแข่งขันของคุณ



5

หากคุณจำเป็นต้องใช้ regex เพื่อกรองผลลัพธ์บางอย่างและจากนั้นใช้เฉพาะกลุ่มการบันทึกคุณสามารถทำสิ่งต่อไปนี้:

str = "Leesburg, Virginia  20176"
state_regex = Regexp.new(/,\s*([A-Za-z]{2,})\s*\d{5,}/)
# looks for the comma, possible whitespace, captures alpha,
# looks for possible whitespace, looks for zip

> str[state_regex]
=> ", Virginia  20176"

> str[state_regex, 1] # use the capture group
=> "Virginia"


0

$ ตัวแปรถูกกำหนดให้จับคู่ในบล็อกเท่านั้น:

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/) { "#{ $1.strip }" }

นี่เป็นวิธีเดียวในการเรียกใช้เมธอดในการแข่งขัน การดำเนินการนี้จะไม่เปลี่ยนแปลงการจับคู่เฉพาะstrip"\ 1" (ปล่อยให้ไม่มีการเปลี่ยนแปลง):

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1".strip)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.