Ekstrak substring dari string di Ruby menggunakan ekspresi reguler


130

Bagaimana saya bisa mengekstraksi substring dari dalam string di Ruby?

Contoh:

String1 = "<name> <substring>"

Saya ingin mengekstrak substringdari String1(yaitu segala sesuatu dalam kemunculan terakhir dari <dan >).

Jawaban:


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

scanmenciptakan sebuah array yang, untuk masing-masing <item>in String1berisi teks antara <dan >dalam array satu elemen (karena ketika digunakan dengan regex yang berisi grup penangkap, pemindaian menciptakan sebuah array yang berisi tangkapan untuk setiap pertandingan). lastmemberi Anda yang terakhir dari array itu dan firstkemudian memberi Anda string di dalamnya.


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

Tidak perlu digunakan scan, jika kita hanya butuh satu hasil.
Tidak perlu menggunakan Python match, ketika kita memiliki Ruby String[regexp,#].

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

catatan: str[regexp, capture] → new_str or nil


37
Tidak perlu mendiskreditkan solusi lain yang sah (dan mungkin saya berpendapat, lebih mudah dibaca).
coreyward

41
@coreyward, jika mereka lebih baik, tolong, bantah itu. Sebagai contoh, solusi sepp2k lebih fleksibel, dan itulah mengapa saya menunjuk if we need only one resultsolusi saya. Dan match()[]lebih lambat, karena itu dua metode, bukan satu.
Nakilon

4
Ini adalah yang tercepat dari semua metode yang disajikan, tetapi bahkan metode paling lambat hanya membutuhkan 4,5 mikrodetik pada mesin saya. Saya tidak peduli untuk berspekulasi mengapa metode ini lebih cepat. Dalam kinerja, spekulasi tidak berguna . Hanya pengukuran yang diperhitungkan.
Wayne Conrad

8
Saya menemukan solusi ini lebih mudah dan to the point (karena saya baru di Ruby). Terima kasih.
Ryan H.

@Nakilon Readability dapat melebihi perbedaan kinerja yang kecil ketika mempertimbangkan kesuksesan keseluruhan produk dan tim, jadi coreyward membuat komentar yang valid. Yang mengatakan, saya pikir string[regex]bisa sama terbaca dalam skenario ini, jadi itulah yang saya gunakan secara pribadi.
Nick

24

Anda dapat menggunakan ekspresi reguler untuk itu dengan mudah ...

Mengizinkan spasi di sekitar kata (tetapi tidak disimpan):

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

Atau tanpa spasi diizinkan:

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

1
Saya tidak yakin bahwa yang terakhir <>benar-benar harus menjadi hal terakhir dalam string. Jika mis. String foo <bar> bazdibolehkan (dan seharusnya memberikan hasilnya bar), ini tidak akan berfungsi.
sepp2k

Saya hanya pergi berdasarkan string sampel yang dia berikan.
coreyward

10

Berikut ini pendekatan yang sedikit lebih fleksibel menggunakan matchmetode ini. Dengan ini, Anda dapat mengekstraksi lebih dari satu string:

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"

3

Scan yang lebih sederhana adalah:

String1.scan(/<(\S+)>/).last
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.