str = "Hello☺ World☹"
La sortie attendue est:
"Hello:) World:("
Je peux le faire: str.gsub("☺", ":)").gsub("☹", ":(")
Existe-t-il un autre moyen pour que je puisse le faire en un seul appel de fonction?. Quelque chose comme:
str.gsub(['s1', 's2'], ['r1', 'r2'])
Depuis Ruby 1.9.2, String#gsub
accepte le hachage comme deuxième paramètre pour le remplacement par des clés correspondantes. Vous pouvez utiliser une expression régulière pour faire correspondre la sous-chaîne qui doit être remplacée et passer le hachage pour les valeurs à remplacer.
Comme ça:
'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*') #=> "h3ll*"
'(0) 123-123.123'.gsub(/[()-,. ]/, '') #=> "0123123123"
Dans Ruby 1.8.7, vous obtiendriez la même chose avec un bloc:
dict = { 'e' => 3, 'o' => '*' }
'hello'.gsub /[eo]/ do |match|
dict[match.to_s]
end #=> "h3ll*"
Configurer une table de mappage:
map = {'☺' => ':)', '☹' => ':(' }
Ensuite, construisez une expression régulière:
re = Regexp.new(map.keys.map { |x| Regexp.escape(x) }.join('|'))
Et enfin, gsub
:
s = str.gsub(re, map)
Si vous êtes coincé dans un terrain de 1,8, alors:
s = str.gsub(re) { |m| map[m] }
Vous avez besoin du Regexp.escape
là au cas où tout ce que vous voulez remplacer a une signification particulière dans une expression régulière. Ou, grâce à steenslag, vous pouvez utiliser:
re = Regexp.union(map.keys)
et le devis sera pris en charge pour vous.
Vous pouvez faire quelque chose comme ça:
replacements = [ ["☺", ":)"], ["☹", ":("] ]
replacements.each {|replacement| str.gsub!(replacement[0], replacement[1])}
Il peut y avoir une solution plus efficace, mais cela rend au moins le code un peu plus propre
Tard dans la soirée, mais si vous souhaitez remplacer certains caractères par un, vous pouvez utiliser une expression régulière
string_to_replace.gsub(/_|,| /, '-')
Dans cet exemple, gsub remplace les traits de soulignement (_), les virgules (,) ou () par un tiret (-)
Vous pouvez également utiliser tr pour remplacer plusieurs caractères dans une chaîne à la fois,
Par exemple, remplacer "h" par "m" et "l" par "t"
"hello".tr("hl", "mt")
=> "metto"
semble simple, soigné et plus rapide (pas beaucoup de différence cependant) que gsub
puts Benchmark.measure {"hello".tr("hl", "mt") }
0.000000 0.000000 0.000000 ( 0.000007)
puts Benchmark.measure{"hello".gsub(/[hl]/, 'h' => 'm', 'l' => 't') }
0.000000 0.000000 0.000000 ( 0.000021)
Un autre moyen simple et pourtant facile à lire est le suivant:
str = '12 ene 2013'
map = {'ene' => 'jan', 'abr'=>'apr', 'dic'=>'dec'}
map.each {|k,v| str.sub!(k,v)}
puts str # '12 jan 2013'
Riffing sur réponse de naren ci-dessus , j'irais avec
tr = {'a' => '1', 'b' => '2', 'z' => '26'}
mystring.gsub(/[#{tr.keys}]/, tr)
Donc 'zebraazzeebra'.gsub(/[#{tr.keys}]/, tr)
renvoie "26e2r112626ee2r1"