Перетворити рядок у рубін регулярного виразу


118

Мені потрібно перетворити рядок типу "/ [\ w \ s] + /" у регулярний вираз.

"/[\w\s]+/" => /[\w\s]+/

Я спробував використовувати різні Regexpметоди, такі як:

Regexp.new("/[\w\s]+/") => /\/[w ]+\//, аналогічно Regexp.compileі Regexp.escape. Але жоден з них не повертається так, як я очікував.

Далі ще я спробував зняти відхилення від косого кута:

Regexp.new("[\w\s]+") => /[w ]+/ Але не пощастило.

Тоді я спробував це зробити просто:

str = "[\w\s]+"
=> "[w ]+"

Він тікає. Тепер, як рядок може залишитися таким, який він є, і перетворити на об'єкт regexp?

Відповіді:


149

Виглядає, що тут вам потрібно, щоб початковий рядок був в одиничних лапках (див. Цю сторінку )

>> str = '[\w\s]+'
 => "[\\w\\s]+" 
>> Regexp.new str
 => /[\w\s]+/ 

137

Щоб було зрозуміло

  /#{Regexp.quote(your_string_variable)}/

теж працює

редагувати: завернув your_string_variable в Regexp. цитата, для правильності.


3
Щойно з’ясував, що не можна додавати варіанти таким чином, як /#{your_regex}/#{options}.
pduersteler

Я гадаю, що ти говориш про Рейлів? optionsце Хеш, а Рубі не так динамічно =)
Сергій Герасимов

2
Це не робить те, про що запитує ОП у Ruby 2.1, він перетворює "[\ w \ s] +" => / [w] + /
Лука Шпіллер

1
Зверніть увагу, що відповідь була надана у 2012 році :) У той час все було ідеально
Сергій Герасимов

4
Це був ідеальний рік.
Нафтулі Кей

35

Цей спосіб безпечно уникне всіх символів із спеціальним значенням:

/#{Regexp.quote(your_string)}/

Наприклад, .буде уникнути, оскільки його інакше трактують як "будь-який персонаж".

Не забудьте використовувати рядок з одним котируванням, якщо ви не хочете, щоб запускалася регулярна інтерполяція рядків, де зворотна косої риси має особливе значення.


2
Приємно, тому що він пояснює, як ми можемо захистити змінну рядка, яка може містити знаки (такі як +.), які будуть інтерпретовані в Regexp.
rchampourlier

1
Це не робить те, про що запитує ОП у Ruby 2.1, він перетворює "[\ w \ s] +" => / [w \] \ + /
Лука Spiller

@LucaSpiller вам потрібно використовувати рядок з цитуванням, зворотний косий рисок розглядається як особливий символ у рядках з подвійним цитуванням, тому напр. "\n"Це новий рядок, але '\n'це не так.
пісок

8

Використання% notation:

%r{\w+}m => /\w+/m

або

regex_string = '\W+'
%r[#{regex_string}]

З довідки :

% r [] Інтерпольований Regexp (прапори можуть з'являтися після закритого роздільника)


Це не робить те, що ОП просить у Ruby 2.1, він перетворює "[\ w \ s] +" => / [ws] + /
Лука Spiller

1
@Luca Spiller, дякую, там слід використовувати одинарні лапки, я оновлю відповідь.
BitOfUniverse

5

Дорогоцінний камінь to_regexp може зробити роботу.

"/[\w\s]+/".to_regexp => /[\w\s]+/

Ви також можете використовувати модифікатор:

'/foo/i'.to_regexp => /foo/i

Нарешті, ви можете бути лінішими за допомогою: виявити

'foo'.to_regexp(detect: true)     #=> /foo/
'foo\b'.to_regexp(detect: true)   #=> %r{foo\\b}
'/foo\b/'.to_regexp(detect: true) #=> %r{foo\b}
'foo\b/'.to_regexp(detect: true)  #=> %r{foo\\b/}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.