Convertir une chaîne en expression régulière ruby

118

J'ai besoin de convertir une chaîne comme "/ [\ w \ s] + /" en expression régulière.

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

J'ai essayé d'utiliser différentes Regexpméthodes comme:

Regexp.new("/[\w\s]+/") => /\/[w ]+\//, de même Regexp.compileet Regexp.escape. Mais aucun d'entre eux ne revient comme je m'y attendais.

De plus, j'ai essayé de supprimer les contre-obliques:

Regexp.new("[\w\s]+") => /[w ]+/ Mais pas de chance.

Ensuite, j'ai essayé de faire simple:

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

Il s'échappe. Maintenant, comment la chaîne pourrait-elle rester telle quelle et se convertir en un objet d'expression régulière?

cmthakur
la source

Réponses:

149

On dirait qu'ici, vous avez besoin que la chaîne initiale soit entre guillemets simples (reportez - vous à cette page )

>> str = '[\w\s]+'
 => "[\\w\\s]+" 
>> Regexp.new str
 => /[\w\s]+/ 
Alony
la source
137

Pour être clair

  /#{Regexp.quote(your_string_variable)}/

fonctionne aussi

edit: a encapsulé your_string_variable dans Regexp.quote, par souci d'exactitude.

Sergey Gerasimov
la source
3
Je viens de découvrir que vous ne pouvez pas ajouter d'options de cette façon, comme /#{your_regex}/#{options}.
pduersteler
Je suppose que vous parlez de Rails? optionsest un Hash, et Ruby n'est pas tellement dynamique =)
Sergey Gerasimov
2
Cela ne fait pas ce que OP demande sur Ruby 2.1, il convertit "[\ w \ s] +" => / [w] + /
Luca Spiller
1
Veuillez noter que la réponse a été donnée en 2012 année :) A cette époque, tout était parfait
Sergey Gerasimov
4
Ce fut une année parfaite.
Naftuli Kay
35

Cette méthode échappera en toute sécurité à tous les caractères ayant une signification particulière:

/#{Regexp.quote(your_string)}/

Par exemple, .sera échappé, car autrement interprété comme «n'importe quel caractère».

N'oubliez pas d'utiliser une chaîne entre guillemets, sauf si vous souhaitez que l'interpolation de chaîne régulière se déclenche, où la barre oblique inverse a une signification particulière.

Sandstrom
la source
2
Bien car il explique comment nous pouvons protéger la variable chaîne qui peut contenir des signes (tels que +.) qui seraient interprétés dans l'expression rationnelle.
rchampourlier
1
Cela ne fait pas ce que OP demande sur Ruby 2.1, il convertit "[\ w \ s] +" => / [w \] \ + /
Luca Spiller
@LucaSpiller vous devez utiliser une chaîne entre guillemets simples, la barre oblique inverse est traitée comme un caractère spécial dans les chaînes entre guillemets, c'est pourquoi par exemple "\n"est une nouvelle ligne mais '\n'ne l'est pas.
sandstrom
8

Utilisation de la notation%:

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

ou

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

De l' aide :

% r [] Expression régulière interpolée (des indicateurs peuvent apparaître après le délimiteur de fermeture)

BitOfUniverse
la source
Cela ne fait pas ce que OP demande sur Ruby 2.1, il convertit "[\ w \ s] +" => / [ws] + /
Luca Spiller
1
@Luca Spiller, merci, des guillemets simples devraient être utilisés ici, je vais mettre à jour la réponse.
BitOfUniverse
5

Le gem to_regexp peut faire le travail.

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

Vous pouvez également utiliser le modificateur:

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

Enfin, vous pouvez être plus paresseux en utilisant: 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/}
Ryan
la source