Interpolacja łańcucha znaków do wyrażenia regularnego

Muszę zastąpić wartość łańcucha w moim wyrażeniu regularnym w Ruby. Czy jest na to łatwy sposób? Na przykład:

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
 123
Author: Andrew Marshall, 2008-09-29

7 answers

Tak samo jak wstawianie napisów.

if goo =~ /#{Regexp.quote(foo)}/
#...
 228
Author: Jonathan Lonowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 18:53:54

Zauważ, że Regexp.quote W odpowiedź Jona L. jest ważna!

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

Jeśli tylko zrobisz "oczywistą" wersję:

if goo =~ /#{foo}/

Następnie okresy w tekście dopasowania są traktowane jako symbole wieloznaczne regexp i "0.0.0.0" będą pasowały "0a0b0c0".

Zauważ również, że jeśli naprawdę chcesz tylko sprawdzić dopasowanie fragmentu, możesz po prostu zrobić

if goo.include?(foo)

Który nie wymaga dodatkowego cytowania ani martwienia się o znaki specjalne.

 94
Author: glenn mcdonald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 23:06:58
Regexp.compile(Regexp.escape(foo))
 6
Author: Markus Jarderot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-15 20:43:50

Prawdopodobnie Regexp.escape(foo) byłby punktem wyjścia, ale czy istnieje dobry powód, dla którego nie można użyć bardziej konwencjonalnego wyrażenia-interpolacji: "my stuff #{mysubstitutionvariable}"?

Możesz również użyć !goo.match(foo).nil? z literalnym ciągiem znaków.

 6
Author: JasonTrue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-27 00:12:16

Użyj Wyrażenia Regularnego.nowy:

if goo =~ Regexp.new(foo) # Evaluates to /0.0.0.0/
 3
Author: Jeremy Ruten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 18:52:42

Oto ograniczona, ale przydatna inna odpowiedź:

Odkryłem, że mogę łatwo wstawić do wyrażenia regularnego bez użycia wyrażenia regularnego.quote lub Regexp.escape jeśli użyłem tylko pojedynczych cudzysłowów na moim ciągu wejściowym: (dopasowanie adresu IP)

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"

Pojedyncze cudzysłowy interpretują tylko \ \ i \'.

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

To pomogło mi, gdy potrzebowałem użyć tej samej długiej porcji regex kilka razy. Nie uniwersalny, ale pasuje do przykład pytania, jak sądzę.

 2
Author: Plasmarob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-31 22:17:56
foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 

puts "success!" if goo =~ /#{foo}/
 -2
Author: Mike Breen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 18:54:02