用Ruby替换字符串中的字母

时间:2014-07-13 20:43:01

标签: ruby string replace

我想使用以下映射替换字符串中的字母:

letters = ("a".."z").to_a.zip(("b".."z").to_a.push("a"))
[["a", "b"], ["b", "c"], ["c", "d"], ["d", "e"], ["e", "f"], ["f", "g"], ["g", "h"], ["h", "i"], ["i", "j"], ["j", "k"], ["k", "l"], ["l", "m"], ["m", "n"], ["n", "o"], ["o", "p"], ["p", "q"], ["q", "r"], ["r", "s"], ["s", "t"], ["t", "u"], ["u", "v"], ["v", "w"], ["w", "x"], ["x", "y"], ["y", "z"], ["z", "a"]]

从这里我只想替换字符串中的所有字母,所以我正在尝试的是

str = "Somebody help I am on drugs and can't program! Just kidding."

letters.each {|letter| str.gsub!(letter[0],letter[1])}

puts str

返回

Saaaaaaa aaaa I aa aa aaaaa aaa aaa'a aaaaaaa! Jaaa aaaaaaa.

出于某种原因,我想要替换的东西被替换为a并忽略我在开头创建的映射。有谁知道发生了什么?我从Ruby multiple string replacement得到了这个想法,但由于某种原因,这并不适用于我的例子。

4 个答案:

答案 0 :(得分:7)

replace_with = (('b'..'z').to_a + ['a']).join('')
str = "Somebody help I am on drugs and can't program! Just kidding."

puts str.tr('a-z', replace_with)
# "Spnfcpez ifmq I bn po esvht boe dbo'u qsphsbn! Jvtu ljeejoh."

替换大写字母str.downcase.tr('a-z', replace_with)

HTH

编辑:手动更换:

letters = Hash[('a'..'z').to_a.zip(('a'..'z').to_a.rotate)] # Thanks to @Jonathan
str = "Somebody help I am on drugs and can't program! Just kidding."
puts str.chars.inject([]) { |result, char| result << (letters[char] || char) }.join
# "Spnfcpez ifmq I bn po esvht boe dbo'u qsphsbn! Jvtu ljeejoh."

答案 1 :(得分:3)

这是另一种方式,使用String#gsub的形式来取一个块:

str = "Somebody help I am on drugs and can't program! Just kidding."

str.gsub(/[a-z]/) { |c| (?a.ord + (c.ord + 1 - ?a.ord) % 26).chr }
  #=> "Spnfcpez ifmq I bn po esvht boe dbo'u qsphsbn! Jvtu ljeejoh."

答案 2 :(得分:3)

您可以使用String#tr的范围表示法:

str = "Somebody help I am on drugs and can't program! Just kidding."

str.tr('a-z', 'b-za')
#=> "Spnfcpez ifmq I bn po esvht boe dbo'u qsphsbn! Jvtu ljeejoh."

String#gsub的哈希替换:

mapping = ("a".."z").zip(("a".."z").to_a.rotate).to_h
#=> {"a"=>"b", "b"=>"c", "c"=>"d", "d"=>"e", "e"=>"f", "f"=>"g", "g"=>"h", "h"=>"i", "i"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"o", "o"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"u", "u"=>"v", "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"a"}

str.gsub(Regexp.union(mapping.keys), mapping)
#=> "Spnfcpez ifmq I bn po esvht boe dbo'u qsphsbn! Jvtu ljeejoh."

答案 3 :(得分:2)

所以我跑了这个

letters = ("a".."z").to_a.zip(("b".."z").to_a.push("a"))[["a", "b"], ["b", "c"], ["c", "d"], ["d", "e"], ["e", "f"], ["f", "g"], ["g", "h"], ["h", "i"], ["i", "j"], ["j", "k"], ["k", "l"], ["l", "m"], ["m", "n"], ["n", "o"], ["o", "p"], ["p", "q"], ["q", "r"], ["r", "s"], ["s", "t"], ["t", "u"], ["u", "v"], ["v", "w"], ["w", "x"], ["x", "y"], ["y", "z"], ["z", "a"]]
str = "Somebody help I am on drugs and can't program! Just kidding."

letters.each do |letter|
   puts "#{letter[0]} #{letter[1]}"
   str.gsub!(letter[0], letter[1])
   puts str
end

,输出

a b
Somebody help I bm on drugs bnd cbn't progrbm! Just kidding.
b c
Somecody help I cm on drugs cnd ccn't progrcm! Just kidding.
c d
Somedody help I dm on drugs dnd ddn't progrdm! Just kidding.
d e
Someeoey help I em on erugs ene een't progrem! Just kieeing.
e f
Somffofy hflp I fm on frugs fnf ffn't progrfm! Just kiffing.
f g
Somggogy hglp I gm on grugs gng ggn't progrgm! Just kigging.
g h
Somhhohy hhlp I hm on hruhs hnh hhn't prohrhm! Just kihhinh.
h i
Somiioiy iilp I im on iruis ini iin't proirim! Just kiiiini.
i j
Somjjojy jjlp I jm on jrujs jnj jjn't projrjm! Just kjjjjnj.
j k
Somkkoky kklp I km on kruks knk kkn't prokrkm! Just kkkkknk.
k l
Somlloly lllp I lm on lruls lnl lln't prolrlm! Just lllllnl.
l m
Sommmomy mmmp I mm on mrums mnm mmn't promrmm! Just mmmmmnm.
m n
Sonnnony nnnp I nn on nruns nnn nnn't pronrnn! Just nnnnnnn.
n o
Sooooooy ooop I oo oo oruos ooo ooo't prooroo! Just ooooooo.
o p
Sppppppy pppp I pp pp prups ppp ppp't prpprpp! Just ppppppp.
p q
Sqqqqqqy qqqq I qq qq qruqs qqq qqq't qrqqrqq! Just qqqqqqq.
q r
Srrrrrry rrrr I rr rr rrurs rrr rrr't rrrrrrr! Just rrrrrrr.
r s
Sssssssy ssss I ss ss ssuss sss sss't sssssss! Just sssssss.
s t
Stttttty tttt I tt tt ttutt ttt ttt't ttttttt! Jutt ttttttt.
t u
Suuuuuuy uuuu I uu uu uuuuu uuu uuu'u uuuuuuu! Juuu uuuuuuu.
u v
Svvvvvvy vvvv I vv vv vvvvv vvv vvv'v vvvvvvv! Jvvv vvvvvvv.
v w
Swwwwwwy wwww I ww ww wwwww www www'w wwwwwww! Jwww wwwwwww.
w x
Sxxxxxxy xxxx I xx xx xxxxx xxx xxx'x xxxxxxx! Jxxx xxxxxxx.
x y
Syyyyyyy yyyy I yy yy yyyyy yyy yyy'y yyyyyyy! Jyyy yyyyyyy.
y z
Szzzzzzz zzzz I zz zz zzzzz zzz zzz'z zzzzzzz! Jzzz zzzzzzz.
z a
Saaaaaaa aaaa I aa aa aaaaa aaa aaa'a aaaaaaa! Jaaa aaaaaaa.

如您所见,您的代码会慢慢替换每个字母,所以最后每个字母都变为z并被a替换

对此的解决方案就是像这样反复迭代

letters.reverse_each do |letter|
   str.gsub!(letter[0], letter[1])
end

输出

Spnfcpez ifmq I bn po esvht boe dbo'u qsphsbn! Jvtu ljeejoh.