1

I have a string in Ruby:

The animal_name is located in the some_place 

How do I replace animal_name by "fish" and some_place by "lake"

I've used sentence.sub! 'animal_name', 'fish' which works great for one word but I'm only allowed 2 parameters therefore I can't change different kinds of words at the same time.

I want to do something like:

sentence.sub! ('animal_name' => 'fish', 'some_place' => 'lake')

Any ideas on how to do that ?

1
  • I believe @steenslag's use of gsub with a hash is the normal way one would perform the desired substitutions. Commented Jan 4, 2020 at 20:17

3 Answers 3

3

That's because sub! can be invoked in three ways:

sub(pattern, replacement) → new_str
sub(pattern, hash) → new_str
sub(pattern) {|match| block } → new_str 

But you're not using any of those forms. You're passing just the hash, so you still need the pattern for that.

But, that's not going to work as you expect because sub replaces only the first match from the pattern:

From the docs:
Returns a copy of str with the first occurrence of pattern replaced by the second argument.

So you could try using gsub instead (or gsub!), but always passing the pattern:

p 'The animal_name is located in the some_place'.gsub(/\b\w+_.*?\b/, 'animal_name' => 'fish', 'some_place' => 'lake')
# "The fish is located in the lake"

(Notice, the regex is just an example. It's the best I can do with just one example.)

Sign up to request clarification or add additional context in comments.

Comments

2

You can use gsub (docs here) providing a block, where you decide which is the right value to replace each of the words:

sentence = 'The animal_name is located in the some_place'
mapping = {'animal_name' => 'fish', 'some_place' => 'lake'}
sentence.gsub(/#{mapping.keys.join('|')}/){|w| mapping[w]}

which returns The fish is located in the lake.

Comments

2

Regexp#union is nice for providing a pattern:

sentence = 'The animal_name is located in the some_place'
mapping = {'animal_name' => 'fish', 'some_place' => 'lake'}

p sentence.gsub(Regexp.union(mapping.keys), mapping)

1 Comment

A variant is map = mapping.tap { |map| map.default_proc= ->(h,k) {k} }; sentence.gsub(/\S+/, map).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.