Trả lại trận đấu đầu tiên của Ruby regex


97

Tôi đang tìm một cách để thực hiện một trận đấu regex trên một chuỗi trong Ruby và nó bị đoản mạch ở trận đấu đầu tiên.

Chuỗi mà tôi đang xử lý dài và từ những gì nó trông giống như cách chuẩn ( matchphương thức) sẽ xử lý toàn bộ, thu thập từng kết quả khớp và trả về một đối tượng MatchData chứa tất cả các kết quả phù hợp.

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

Câu trả lời:


134

Bạn có thể thử variableName[/regular expression/]. Đây là một ví dụ đầu ra từ 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"

Đây không phải là làm một trận đấu và trả về kết quả đầu tiên đằng sau hậu trường?
Gishu

7
Sau một số đo điểm chuẩn với các chuỗi độ dài khác nhau và xem xét nguồn C, hóa ra Regex.match bị đoản mạch và chỉ tìm thấy kết quả phù hợp đầu tiên.
Daniel Beardsley

3
Gọn gàng, không biết về phím tắt này.
Pierre

Có một số tài liệu về phím tắt này không? Tôi đã tìm kiếm cao và thấp cho những gì tôi nghĩ là một nhiệm vụ tương đối đơn giản và chỉ giải quyết được vấn đề của tôi sau khi tìm thấy điều này. Cảm ơn!
dmourati

5
@dmourati Bạn có thể tìm thấy tính năng này được ghi lại trong Chuỗi # [] . Cảm ơn bạn đã hỏi về tài liệu, vì khi đọc tài liệu, tôi đã tìm thấy captuređối số - cho phép bạn trả về một ảnh chụp thay vì đối sánh đầy đủ.
slothbear

68

Bạn có thể sử dụng []: (giống như 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
câu trả lời hoàn chỉnh tốt nhất
akostadinov

23

Nếu chỉ tồn tại một trận đấu là quan trọng, bạn có thể đi với

/regexp/ =~ "string"

Dù bằng cách nào, matchchỉ nên trả lại lần truy cập đầu tiên, trong khi scantìm kiếm trong toàn bộ chuỗi. Do đó nếu

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

8

Tôi không chắc liệu tính năng này có tuyệt vời hay hoàn toàn điên rồ, nhưng regex của bạn có thể xác định các biến cục bộ.

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

(Lấy từ http://ruby-doc.org/core-2.1.1/Regexp.html ).


Tính năng tuyệt vời! Chỉ những gì tôi cần
RaphaMex

Lưu ý: nó chỉ hoạt động khi regex =~ string", not when string = ~ regex`
Christopher Oezbek

2

Biểu thức chính quy (regex) không là gì ngoài một máy trạng thái hữu hạn (FSM).

FSM cố gắng trả lời câu hỏi "Trạng thái này có khả thi hay không?"

Nó tiếp tục cố gắng tạo ra một đối sánh mẫu cho đến khi tìm thấy một đối sánh (thành công) hoặc cho đến khi tất cả các đường được khám phá và không tìm thấy đối sánh nào (thất bại).

Về thành công, câu hỏi "Trạng thái này có thể xảy ra hay không?" đã được trả lời với một "có". Do đó, không cần đối sánh nữa và regex trả về.

Xem điều nàyđiều này để biết thêm về điều này.

Hơn nữa: đây là một ví dụ thú vị để chứng minh cách thức hoạt động của regex. Ở đây, một regex được sử dụng để phát hiện xem một số cho trước có phải là số nguyên tố hay không. Ví dụ này bằng perl, nhưng nó cũng có thể được viết bằng ruby.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.