Marcelo Camargo
Marcelo Camargo

Reputation: 2298

Array replacement in Ruby

I'm trying to do a multiple replacement in Ruby. I would do in PHP:

$text = "bar foo baz doom?";
$before = ["bar", "foo", "baz"];
$after = ["goto", "if", "else"];
$result = preg_replace($before, $after, $text);
// output: goto if else doom?

In Ruby, something like below gives me an error:

text = "bar foo baz doom?"
before = [/bar/, /foo/, /baz/]
after = ['goto', 'if', 'else']
result = text.gsub(before, after)
# => Can't convert Array into Regexp

Can you help me?

Upvotes: 0

Views: 179

Answers (6)

nishu
nishu

Reputation: 1493

You can achieve this by using regex in ruby 1.9.2 and above.

class String
  def preg_replace(before, after)
    gsub Regexp.union(before), Hash[before.zip(after)]
  end
end


text = "bar foo baz doom?"
before = ["bar", "foo", "baz"]
after = ["goto", "if", "else"]
text.preg_replace before, after
#=> "goto if else doom?"

Upvotes: 0

Zini
Zini

Reputation: 914

text = "bar foo baz doom?"
before = [/bar/, /foo/, /baz/]
after = ['goto', 'if', 'else']
result = text.dup
before.each_index { |i| result.gsub!(before[i] ,after[i]) }
result

Upvotes: 0

fbonetti
fbonetti

Reputation: 6672

text = "bar foo baz doom?"
before = [/bar/, /foo/, /baz/]
after = ['goto', 'if', 'else']

before.each_with_index do |reg, i|
  text.gsub!(reg, after[i])
end

Upvotes: 1

Arup Rakshit
Arup Rakshit

Reputation: 118271

Use Hash with #gsub :-

text = "bar foo baz doom?"
before = ["bar", "foo", "baz"]
after = ["goto", "if", "else"]

hash = Hash[before.zip(after)]
  #=> {"bar"=>"goto", "foo"=>"if", "baz"=>"else"}
text.gsub(/\w+/) { |m| hash[m] || m }
  #=> "goto if else doom?"

Upvotes: 3

Grych
Grych

Reputation: 2901

Another way to archive this

output = text.split.map { |x| before.index(x) ? after[before.index(x)] : x }.join(' ')

output contains "goto if else doom?", as requested.

Upvotes: 0

hahcho
hahcho

Reputation: 1409

I don't think there is a corresponding method in ruby. You can zip the before and after and apply every substitution separetly.Here is an example, I have used dup to prevent mutating the original content.

text = "bar foo baz doom?"
before = [/bar/, /foo/, /baz/]
after = ['goto', 'if', 'else']
result = text.dup
before.zip(after).each { |pattern, replace| result.gsub!(pattern, replace) }
result

Upvotes: 1

Related Questions