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

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:



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.


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.



3

Verwenden Sie Regexp.new:

if goo =~ Regexp.new(foo) # Evaluates to /0.0.0.0/

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.


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}/

2
Nein, dies ergibt ein fehlerhaftes "wahr" für "hier ist noch etwas anderes 070x0! 0", da die Punkte Regexp-Platzhalter sind.
Glenn McDonald
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.