str = "Hello☺ World☹"
Die erwartete Ausgabe ist:
"Hello:) World:("
Ich kann dies tun: str.gsub("☺", ":)").gsub("☹", ":(")
Gibt es eine andere Möglichkeit, dies in einem einzigen Funktionsaufruf zu tun? Etwas wie:
str.gsub(['s1', 's2'], ['r1', 'r2'])
String#tr
, den Trick zu machen, aber der Ersatz durch mehrere Zeichen bedeutet, dass ich das nicht verwenden kann.Antworten:
Akzeptiert seit Ruby 1.9.2
String#gsub
Hash als zweiten Parameter zum Ersetzen durch übereinstimmende Schlüssel. Sie können einen regulären Ausdruck verwenden, um die zu ersetzende Teilzeichenfolge abzugleichen und einen Hash für zu ersetzende Werte zu übergeben.So was:
'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*') #=> "h3ll*" '(0) 123-123.123'.gsub(/[()-,. ]/, '') #=> "0123123123"
In Ruby 1.8.7 würden Sie dasselbe mit einem Block erreichen:
dict = { 'e' => 3, 'o' => '*' } 'hello'.gsub /[eo]/ do |match| dict[match.to_s] end #=> "h3ll*"
quelle
tr
.Richten Sie eine Zuordnungstabelle ein:
map = {'☺' => ':)', '☹' => ':(' }
Erstellen Sie dann einen regulären Ausdruck:
re = Regexp.new(map.keys.map { |x| Regexp.escape(x) }.join('|'))
Und schließlich
gsub
:Wenn Sie in 1.8 Land stecken, dann:
s = str.gsub(re) { |m| map[m] }
Sie benötigen das
Regexp.escape
dort, falls etwas, das Sie ersetzen möchten, innerhalb eines regulären Ausdrucks eine besondere Bedeutung hat. Oder dank steenslag können Sie Folgendes verwenden:und das Angebot wird für Sie erledigt.
quelle
map.each { |re, v| ... }
Sie könnten so etwas tun:
replacements = [ ["☺", ":)"], ["☹", ":("] ] replacements.each {|replacement| str.gsub!(replacement[0], replacement[1])}
Es mag eine effizientere Lösung geben, aber dies macht den Code zumindest ein bisschen sauberer
quelle
replacements.each
?each
ist die Sammlung, für die aufgerufen wurde. stackoverflow.com/questions/11596879/…replacements.reduce(str){|str,replacement| str.gsub(replacement[0],replacement[1])}
replacements.inject(str) { |str, (k,v)| str.gsub(k,v) }
und vermeiden, dass Sie tun müssen[0]
und[1]
.Spät zur Party, aber wenn Sie bestimmte Zeichen durch eines ersetzen möchten, können Sie einen regulären Ausdruck verwenden
string_to_replace.gsub(/_|,| /, '-')
In diesem Beispiel ersetzt gsub die Unterstriche (_), Kommas (,) oder () durch einen Bindestrich (-).
quelle
string_to_replace.gsub(/[_- ]/, '-')
Eine andere einfache und dennoch leicht zu lesende Methode ist die folgende:
str = '12 ene 2013' map = {'ene' => 'jan', 'abr'=>'apr', 'dic'=>'dec'} map.each {|k,v| str.sub!(k,v)} puts str # '12 jan 2013'
quelle
Sie können tr auch verwenden, um mehrere Zeichen in einer Zeichenfolge gleichzeitig zu ersetzen.
Ersetzen Sie z. B. "h" durch "m" und "l" durch "t".
"hello".tr("hl", "mt") => "metto"
sieht einfach, ordentlich und schneller aus (allerdings kein großer Unterschied) als 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)
quelle
Nach Narens Antwort oben würde ich mitgehen
tr = {'a' => '1', 'b' => '2', 'z' => '26'} mystring.gsub(/[#{tr.keys}]/, tr)
So
'zebraazzeebra'.gsub(/[#{tr.keys}]/, tr)
kehrt "26e2r112626ee2r1"quelle