如何屏蔽字符串中除了最后四个字符之外的所有字符

use*_*309 2 ruby

我一直在尝试编码练习,以掩盖除了输入的最后四位数或字符之外的所有数字.

我认为我的解决方案有效但看起来有点笨拙.有没有人有关于如何重构它的想法?

这是我的代码:

def mask(string)
  z = string.to_s.length

  if z <= 4
    return string
  elsif z > 4
    array = []
    string1 = string.to_s.chars

    string1[0..((z-1)-4)].each do |s|
      array << "#"
    end

    array << string1[(z-4)..(z-1)]

    puts array.join(", ").delete(", ").inspect     
  end
end
Run Code Online (Sandbox Code Playgroud)

Eri*_*nil 7

积极向前看

一个积极的前瞻使得它很容易.如果任何字符后跟至少4个字符,则会被替换:

"654321".gsub(/.(?=.{4})/,'#')
# "##4321"
Run Code Online (Sandbox Code Playgroud)

这是正则表达式的描述:

r = /
     .        # Just one character
     (?=      # which must be followed by
        .{4}  # 4 characters
     )        #
    /x        # free-spacing mode, allows comments inside regex
Run Code Online (Sandbox Code Playgroud)

请注意,正则表达式一次只匹配一个字符,即使每个匹配最多需要检查5个字符:

"654321".scan(r)
# => ["6", "5"]
Run Code Online (Sandbox Code Playgroud)

/(.)..../ 不起作用,因为每次迭代会消耗5个字符:

"654321".scan(/(.)..../)
# => [["6"]]
"abcdefghij".scan(/(.)..../)
# => [["a"], ["f"]]
Run Code Online (Sandbox Code Playgroud)

如果要参数化未屏蔽字符串的长度,可以使用变量插值:

all_but = 4
/.(?=.{#{all_but}})/
# => /.(?=.{4})/
Run Code Online (Sandbox Code Playgroud)

将其打包成一种方法,它变为:

def mask(string, all_but = 4, char = '#')
  string.gsub(/.(?=.{#{all_but}})/, char)
end

p mask('testabcdef')
# '######cdef'
p mask('1234')
# '1234'
p mask('123')
# '123'
p mask('x')
# 'x'
Run Code Online (Sandbox Code Playgroud)

你也可以根据句子进行调整:

def mask(string, all_but = 4, char = '#')
  string.gsub(/\w(?=\w{#{all_but}})/, char)
end

p mask('It even works for multiple words')
# "It even #orks for ####iple #ords"
Run Code Online (Sandbox Code Playgroud)

关于你的代码的一些注释

string.to_s

命名事物在编程中非常重要,特别是在动态语言中.

string.to_s
Run Code Online (Sandbox Code Playgroud)

如果string确实是一个字符串,则没有任何理由可以调用to_s.

如果string不是字符串,您应该to_s先调用,gsub但也应重命名string为更好的描述:

object.to_s
array.to_s
whatever.to_s
Run Code Online (Sandbox Code Playgroud)

加入

puts array.join(", ").delete(", ").inspect
Run Code Online (Sandbox Code Playgroud)

你想做什么?你可以使用join:

[1,2,[3,4]].join(", ").delete(", ")
# "1234"
[1,2,[3,4]].join
# "1234"
Run Code Online (Sandbox Code Playgroud)

删除

请注意.delete(", "),以任何顺序删除每个逗号和每个空格.它不仅删除", "子串:

",a b,,,   cc".delete(', ')
# "abcc"
["1,2", "3,4"].join(', ').delete(', ')
# "1234"
Run Code Online (Sandbox Code Playgroud)