Interpolieren eines Strings in einen regulären Ausdruck

160

Ich muss den Wert einer Zeichenfolge in meinen regulären Ausdruck in Ruby einsetzen. Gibt es eine einfache Möglichkeit, dies zu tun? Beispielsweise:

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
Chris Bunch
quelle
Versuchen Sie zu sehen, ob foo ein Teilstring von goo ist? Ich denke nicht, dass es klar ist, was Sie fragen.
Neall
Wenn ja, ist goo.include? (Foo) genug!
Glenn McDonald
1
Nein, ich habe nicht versucht zu sehen, ob foo ein Teil von goo ist. Ich musste auch einige Aufnahmen machen, daher hat Include nicht funktioniert.
Chris Bunch

Antworten:

274

Entspricht dem Einfügen von Zeichenfolgen.

if goo =~ /#{Regexp.quote(foo)}/
#...
Jonathan Lonowski
quelle
125

Beachten Sie, dass die Regexp.quotein Jon L. Antwort ist wichtig!

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

Wenn Sie nur die "offensichtliche" Version machen:

if goo =~ /#{foo}/

Dann werden die Punkte in Ihrem Match-Text als Regexp-Platzhalter behandelt und stimmen "0.0.0.0"überein "0a0b0c0".

Beachten Sie auch, dass Sie dies einfach tun können, wenn Sie wirklich nur nach einer Teilzeichenfolgenübereinstimmung suchen möchten

if goo.include?(foo)

Dies erfordert kein zusätzliches Zitieren oder Sorgen um Sonderzeichen.

Glenn McDonald
quelle
3
Beachten Sie, dass die Umkehrung (nicht verwendet .quote()) auch nützlich sein kann, wenn Sie einen regulären Ausdruck mithilfe einer Zeichenfolge erstellen möchten.
Jesse
"Wenn Sie wirklich nur nach einer Teilstring-Übereinstimmung suchen möchten, können Sie einfach if goo.include?(foo)" => True, wenn Sie an der Existenzprüfung interessiert sind. Wenn Sie daran interessiert sind, String.gsub zu ersetzen und bereits zu verwenden, ist Regexp.quote möglicherweise Ihre einzige Option.
Isaac Betesh
Nur um Jesse zu erweitern, falls es nicht offensichtlich ist, bedeutet dies, nur die Zeichenfolge zu übergeben, die Sie nicht benötigen, um zu Regexp.newoder zu entkommen Regexp.compile.
Dylankb
Vielen Dank für die nützliche Erklärung, warum wir Regexp.quote
Wylliam Judd
7

Wäre wahrscheinlich Regexp.escape(foo)ein Ausgangspunkt, aber gibt es einen guten Grund, warum Sie die konventionellere Ausdrucksinterpolation nicht verwenden können : "my stuff #{mysubstitutionvariable}"?

Sie können auch nur !goo.match(foo).nil?eine Literalzeichenfolge verwenden.

JasonTrue
quelle
6
Regexp.compile(Regexp.escape(foo))
Markus Jarderot
quelle
3

Verwenden Sie Regexp.new:

if goo =~ Regexp.new(foo) # Evaluates to /0.0.0.0/
Jeremy Ruten
quelle
3

Hier ist eine begrenzte, aber nützliche andere Antwort:

Ich habe festgestellt, dass ich ohne Regexp.quote oder Regexp.escape problemlos in einen regulären Ausdruck einfügen kann, wenn ich nur einfache Anführungszeichen für meine Eingabezeichenfolge verwendet habe: (eine IP-Adressübereinstimmung)

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"

einfache Anführungszeichen interpretieren nur \\ und \ '.

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

Dies hat mir geholfen, als ich mehrmals denselben langen Teil einer Regex verwenden musste. Nicht universell, passt aber zum Fragenbeispiel, glaube ich.

Plasmarob
quelle
Ich bin gespannt, was von meinem Beitrag hier gehalten wird, aber ich bezweifle, dass er jetzt so weit unten hier zu sehen sein wird.
Plasmarob
-2
foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 

puts "success!" if goo =~ /#{foo}/
Mike Breen
quelle
2
Nein, dies ergibt ein fehlerhaftes "wahr" für "hier ist noch etwas anderes 070x0! 0", da die Punkte Regexp-Platzhalter sind.
Glenn McDonald