Ruby,如何更改字符串的每个单词中的每个“s”,除非“s”是第一个字母

时间:2015-09-25 05:26:14

标签: ruby

尝试创建一个简单的多字符串方法来替换字符串的一些字母(3表示“e”,0表示“o”,1表示“I”,“z”表示“s”(除非“s”是单词中的第一个字母。所以,“儿子sams玫瑰”将改为“sonz samz roz3z”。

除了不更改字符串中每个单词的第一个's'之外,我的所有规范都通过了。我似乎无法使用字符串中的每个字母来处理每个单词,以第一个字母为目标。

class String
  def leetspeak
    word = self.split("")
    new_word = []

    word.each do |i|
      if i == "e"
        new_word.push(3)
      elsif i == "o"
        new_word.push(0)
      elsif i == "I"
        new_word.push(1)
      elsif (i == "s") && ((word.find_index(" ") + 1) != "s")
        new_word.push("z")
      else
        new_word.push(i)
      end
    end
    new_word.join
  end
end

在最后一个elsif上,我以为我可以使用.find_index(“”)+ 1来定位第一个字母,但它不起作用,即使它确实如此,它也不适用于第一个字母。字符串,如果它是“s”。任何帮助,将不胜感激。

4 个答案:

答案 0 :(得分:4)

有很多方法可以实现这一目标。您是否要求此实现使用if / else?否则,下面是一个更简单的一个:

def leetspeak
  self
    .gsub('e', '3')
    .gsub('o', '0')
    .gsub('I', '1')
    .gsub(/(?!^)s/, 'z')
end

/(?!^)s/部分是Regular Expression(或正则表达式),表示所有与s相关的内容,除非它是第一个字符(?!something)negative lookahead^是字符串的开头。 gsub方法全局替换(在整个字符串中)与表达式匹配的任何子字符串,并将其替换为第二个参数。

我确信在性能和清晰度方面都有更好的方法,但我想这个实现应该足够好了。

更新:

我误解了这个问题,我已经使用s代替\b,将{re>从 匹配到任何单词中的每个def leetspeak self .gsub('e', '3') .gsub('o', '0') .gsub('I', '1') .gsub(/(?!\b)s/, 'z') end 匹配<{1}} 3}}

id  Name    Type    Project Place            Start Date              End Date                Details
1   Sai Local   Site    Bangalore   2015-09-03 11:32:47 2015-09-05 11:32:47 test                    
2   Ram Local   IGCAR   Chennai     2015-04-01 15:15:36 2015-04-09 15:15:36 Installation                    
3   Mani    Local   IGCAR   Chennai     2015-04-16 15:16:18 2015-05-21 15:16:18 Training

答案 1 :(得分:1)

您可以使用each_with_index方法。

class String
  def leetspeak
    word = self.split("")
    new_word = []

    word.each_with_index do |i, index|
      if i == "e"
        new_word.push(3)
      elsif i == "o"
        new_word.push(0)
      elsif i == "I"
        new_word.push(1)
      elsif (i == "s") && index != 0
        new_word.push("z")
      else
        new_word.push(i)
      end
    end
    new_word.join
  end
end

"ss".leetspeak
=> "sz"

您可以为每个单词调用leetspeak方法:

"ss roses sams".split(" ").map{|e| e.leetspeak}.join(" ")
=> "sz r0z3z samz"

答案 2 :(得分:0)

我不明白你想要什么,但word.find_index(" ")会返回一个索引,你应该使用这样的索引:

elsif (i == "s") && ((word[word.find_index(" ") + 1]) != "s")

答案 3 :(得分:0)

我的例子:

str = "egad!, she repeated, it's VI o'clock\nI really must go!"

如果我理解正确,可以通过以下几种方式使用哈希:

replacements = { "e"=>"3", "o"=>"0", "I"=>"1", "s"=>"z" }

和正则表达式:

r = /
    [a-rt-z] # match any lower case letter other than s
    |        # or
    (?<=\w)  # match a word character in a positive lookbehind
    s        # match s
    /ix      # case indifferent and extended mode

<强>#1

str.gsub(r) { |s| replacements[s] || s }
  #=> "3gad!, sh3 r3p3at3d, it's V1 0'cl0ck\n1 r3ally muzt g0!" 

<强>#2

replacements.default_proc = ->(_,k) { k }
str.gsub(r, replacements)
  #=> "3gad!, sh3 r3p3at3d, it's V1 0'cl0ck\n1 r3ally muzt g0!"