Interpoler une chaîne dans une regex


160

J'ai besoin de remplacer la valeur d'une chaîne dans mon expression régulière dans Ruby. Y a-t-il un moyen facile de faire ceci? Par exemple:

foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 
if goo =~ /value of foo here dynamically/
  puts "success!"
end

Essayez-vous de voir si foo est une sous-chaîne de goo? Je ne pense pas que ce que vous demandez soit clair.
Neall le

Si c'est le cas, goo.include? (Toto) suffit!
glenn mcdonald

1
Non, je n'essayais pas de voir si foo est une sous-chaîne de goo; J'avais également besoin de faire de la capture, donc inclure ne fonctionnait pas.
Chris Bunch

Réponses:



125

Notez que la Regexp.quotedans la réponse de Jon L. est important!

if goo =~ /#{Regexp.quote(foo)}/

Si vous ne faites que la version "évidente":

if goo =~ /#{foo}/

alors les points de votre texte de correspondance sont traités comme des jokers d'expression régulière et "0.0.0.0"correspondent "0a0b0c0".

Notez également que si vous voulez vraiment simplement vérifier une correspondance de sous-chaîne, vous pouvez simplement faire

if goo.include?(foo)

qui ne nécessite pas de guillemets supplémentaires ni de souci des caractères spéciaux.


3
Notez que l'inverse (ne pas utiliser .quote()) peut également être utile si vous cherchez à construire une expression régulière en utilisant une chaîne.
Jesse

"si vous voulez vraiment simplement vérifier une correspondance de sous-chaîne, vous pouvez simplement faire if goo.include?(foo)" => True lorsque vous souhaitez vérifier l'existence. Si vous souhaitez remplacer et utiliser déjà String.gsub, Regexp.quote peut être votre seule option.
Isaac Betesh

Juste pour ajouter à Jesse au cas où ce ne serait pas évident, cela signifie simplement passer la chaîne de caractères dont vous n'avez pas besoin d'échapper Regexp.newou Regexp.compile.
dylankb

Merci pour l'explication utile des raisons pour lesquelles nous pourrions vouloir utiliser Regexp.quote
Wylliam Judd

7

Probablement Regexp.escape(foo)serait un point de départ, mais est - il une bonne raison pour laquelle vous ne pouvez pas utiliser plus classique expression d'interpolation: "my stuff #{mysubstitutionvariable}"?

En outre, vous pouvez simplement utiliser !goo.match(foo).nil?avec une chaîne littérale.




3

Voici une autre réponse limitée mais utile:

J'ai découvert que je peux facilement insérer dans une regex sans utiliser Regexp.quote ou Regexp.escape si je viens d'utiliser des guillemets simples sur ma chaîne d'entrée: (une adresse IP correspond)

IP_REGEX = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'

my_str = "192.0.89.234 blahblah text 1.2, 1.4" # get the first ssh key 
# replace the ip, for demonstration
my_str.gsub!(/#{IP_REGEX}/,"192.0.2.0") 
puts my_str # "192.0.2.0 blahblah text 1.2, 1.4"

les guillemets simples n'interprètent que \\ et \ '.

http://en.wikibooks.org/wiki/Ruby_Programming/Strings#Single_quotes

Cela m'a aidé lorsque j'ai eu besoin d'utiliser la même portion longue d'une expression régulière plusieurs fois. Pas universel, mais correspond à l'exemple de la question, je crois.


Je suis curieux de savoir ce que l'on pensera de mon message ici, mais je doute qu'il soit vu aussi loin ici maintenant.
Plasmarob

-2
foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 

puts "success!" if goo =~ /#{foo}/

2
Non, cela donnera un "vrai" erroné pour "voici un autre truc 070x0! 0", car les points sont des jokers d'expression régulière.
glenn mcdonald
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.