Преобразование строки в регулярное выражение ruby

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 ]+"

Он убегает. Каким образом строка могла остаться такой, какая она есть, и преобразоваться в объект регулярного выражения?

cmthakur
источник

Ответы:

149

Похоже, здесь вам нужно, чтобы начальная строка была в одинарных кавычках (см. Эту страницу )

>> str = '[\w\s]+'
 => "[\\w\\s]+" 
>> Regexp.new str
 => /[\w\s]+/ 
alony
источник
137

Чтобы быть ясным

  /#{Regexp.quote(your_string_variable)}/

тоже работает

edit: для правильности обернул your_string_variable в Regexp.quote.

Сергей Герасимов
источник
3
Только что выяснил, что нельзя добавлять параметры таким образом, например /#{your_regex}/#{options}.
pduersteler
Я полагаю, вы говорите о Rails? optionsэто Hash, а Ruby не такой уж динамичный =)
Сергей Герасимов
2
Это не выполняет то, что OP запрашивает на Ruby 2.1, оно преобразует "[\ w \ s] +" => / [w] + /
Luca Spiller
1
Обратите внимание, что ответ был дан в 2012 году :) На тот момент все было идеально
Сергей Герасимов
4
Это был идеальный год.
Naftuli Kay
35

Этот метод безопасно экранирует все символы со специальным значением:

/#{Regexp.quote(your_string)}/

Например, .будет экранирован, поскольку иначе он интерпретируется как «любой символ».

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

Сандстр
источник
2
Приятно, потому что он объясняет, как мы можем защитить строковую переменную, которая может содержать знаки (например, +.), которые будут интерпретироваться в Regexp.
rchampourlier
1
Это не выполняет то, что OP запрашивает на Ruby 2.1, оно преобразует "[\ w \ s] +" => / [w \] \ + /
Лука Спиллер
@LucaSpiller, вам нужно использовать строку в одинарных кавычках, обратная косая черта рассматривается как специальный символ в строках с двойными кавычками, поэтому, например, "\n"является новой строкой, но '\n'не является.
Sandstrom
8

Используя обозначение%:

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

или

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

Из справки :

% r [] Интерполированное регулярное выражение (флаги могут появляться после закрывающего разделителя)

BitOfUniverse
источник
Это не выполняет то, что OP запрашивает на Ruby 2.1, оно преобразует "[\ w \ s] +" => / [ws] + /
Лука Спиллер
1
@Luca Spiller, спасибо, там следует использовать одинарные кавычки, я обновлю ответ.
BitOfUniverse
5

Драгоценный камень to_regexp может сделать работу.

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

Вы также можете использовать модификатор:

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

Наконец, вы можете быть более ленивым, используя: detect

'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/}
Райана
источник