Витягніть підрядку з рядка в Ruby, використовуючи регулярний вираз


130

Як я можу витягнути підрядку з рядка в Ruby?

Приклад:

String1 = "<name> <substring>"

Я хочу витягнути substringз нього String1(тобто все в межах останнього появи <та >).

Відповіді:


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

scanстворює масив, який для кожного <item>з String1містить текст між <і >в одноелементному масиві (тому що, коли використовується з регулярним виразом, що містить групи захоплення, сканування створює масив, що містить фіксатори для кожного збігу). lastдає вам останній з цих масивів, а firstпотім дає вам рядок у ньому.


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

Не потрібно використовувати scan, якщо нам потрібен лише один результат.
Немає потреби використовувати Python match, коли у нас є Ruby String[regexp,#].

Дивіться: http://ruby-doc.org/core/String.html#method-i-5B-5D

Примітка: str[regexp, capture] → new_str or nil


37
Не потрібно дискредитувати інші ідеально прийнятні (і я можу припустити, більш зрозумілі) рішення.
coreyward

41
@coreyward, якщо вони кращі, будь ласка, аргументуйте це. Наприклад, рішення sepp2k є більш гнучким, і саме тому я вказав if we need only one resultу своєму рішенні. І match()[]повільніше, бо це два способи замість одного.
Накілон

4
Це найшвидший з усіх представлених методів, але навіть найповільніший метод займає всього 4,5 мікросекунди на моїй машині. Мені не хочеться міркувати, чому цей метод швидший. У виконанні спекуляцій марно . Враховується лише вимірювання.
Уейн Конрад

8
Я вважаю це рішення більш зрозумілим і суттєвим (оскільки я новачок у Рубі). Дякую.
Райан Х.

@Nakilon Читальність може перевищувати невеликі відмінності в продуктивності, враховуючи загальний успіх продукту та команди, тому Coreyward зробив вагомий коментар. Однак, я думаю, що я string[regex]можу бути таким же читабельним у цьому сценарії, тож це я особисто використовував.
Нік

24

Ви можете використовувати звичайний вираз для цього досить легко ...

Дозволити пробіли навколо слова (але не зберігати їх):

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

Або без пробілів:

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

1
Я не впевнений, що останній <>насправді повинен бути останнім у рядку. Якщо, наприклад, рядок foo <bar> bazдозволено (і повинен дати результат bar), це не буде працювати.
sepp2k

Я щойно перейшов на основі зразка, який він надав.
coreyward

10

Ось дещо гнучкіший підхід із використанням matchметоду. За допомогою цього ви можете витягнути більше однієї струни:

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"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.