Trích xuất một chuỗi con từ một chuỗi trong Ruby bằng biểu thức chính quy


130

Làm cách nào tôi có thể trích xuất một chuỗi con từ trong một chuỗi trong Ruby?

Thí dụ:

String1 = "<name> <substring>"

Tôi muốn trích xuất substringtừ String1(tức là mọi thứ trong lần xuất hiện cuối cùng của <>).

Câu trả lời:


134
String1.scan(/<([^>]*)>/).last.first

scantạo ra một mảng mà, đối với mỗi <item>trong String1chứa văn bản giữa <>trong một mảng một yếu tố (vì khi sử dụng với một regex chứa nhóm chụp, quét tạo ra một mảng chứa các ảnh chụp cho mỗi trận đấu). lastcung cấp cho bạn chuỗi cuối cùng và firstsau đó cung cấp cho bạn chuỗi trong đó.


319
"<name> <substring>"[/.*<([^>]*)/,1]
=> "substring"

Không cần sử dụng scan, nếu chúng ta chỉ cần một kết quả.
Không cần sử dụng Python match, khi chúng ta có Ruby String[regexp,#].

Xem: http://ruby-doc.org/core/String.html#method-i-5B-5D

Ghi chú: str[regexp, capture] → new_str or nil


37
Không cần phải làm mất uy tín các giải pháp hoàn toàn hợp lệ khác (và tôi có thể áp đặt, dễ đọc hơn).
coreyward

41
@coreyward, nếu họ tốt hơn, xin vui lòng, tranh luận về nó. Ví dụ: giải pháp của sepp2k linh hoạt hơn và đó là lý do tại sao tôi chỉ ra if we need only one resultgiải pháp của mình. Và match()[]chậm hơn, bởi vì đó là hai phương pháp thay vì một.
Nakilon

4
Đây là phương pháp nhanh nhất trong tất cả các phương pháp được trình bày, nhưng ngay cả phương pháp chậm nhất cũng chỉ mất 4,5 micro giây trên máy của tôi. Tôi không quan tâm để suy đoán tại sao phương pháp này nhanh hơn. Trong hiệu suất, đầu cơ là vô ích . Chỉ đo đếm.
Wayne Conrad

8
Tôi thấy giải pháp này đơn giản hơn và đi vào vấn đề (vì tôi mới biết về Ruby). Cảm ơn.
Ryan H.

@Nakilon Khả năng đọc có thể vượt xa sự khác biệt hiệu suất nhỏ khi xem xét thành công chung của sản phẩm và nhóm, vì vậy, Coreyward đã đưa ra nhận xét hợp lệ. Điều đó nói rằng, tôi nghĩ string[regex]có thể đọc được trong kịch bản này, vì vậy đó là những gì tôi đã sử dụng cá nhân.
Nick

24

Bạn có thể sử dụng một biểu thức chính quy cho điều đó khá dễ dàng

Cho phép khoảng trắng xung quanh từ (nhưng không giữ chúng):

str.match(/< ?([^>]+) ?>\Z/)[1]

Hoặc không có khoảng trắng được phép:

str.match(/<([^>]+)>\Z/)[1]

1
Tôi không chắc chắn rằng cuối cùng <>thực sự cần phải là điều cuối cùng trong chuỗi. Nếu ví dụ: chuỗi foo <bar> bazđược cho phép (và được cho là đưa ra kết quả bar), thì chuỗi này sẽ không hoạt động.
sepp2k

Tôi chỉ đi dựa trên chuỗi mẫu anh ấy cung cấp.
coreyward

10

Đây là một cách tiếp cận linh hoạt hơn một chút bằng cách sử dụng matchphương pháp. Với điều này, bạn có thể trích xuất nhiều hơn một chuỗi:

s = "<ants> <pants>"
matchdata = s.match(/<([^>]*)> <([^>]*)>/)

# Use 'captures' to get an array of the captures
matchdata.captures   # ["ants","pants"]

# Or use raw indices
matchdata[0]   # whole regex match: "<ants> <pants>"
matchdata[1]   # first capture: "ants"
matchdata[2]   # second capture: "pants"

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.