是否有一种Ruby方式来替换字符串的后四位数字(不包括空格?

问题描述 投票:0回答:3

我必须找到一种使后四个数字字符匿名的方法。出现一个电话号码字符串,例如“ +36 6 41 88 75 22”(或任何其他格式,例如“ +36641887522”或+36 6 418 875 22等),我希望我的代码输出“ +36 6 41 88 XX XX“。

phoneNumber = "+36 6 41 88 75 22"我找到的最接近我想要的选择的正则表达式是:/\d.{4}$/这很方便,因为lastFour = phone.scan(/\d.{4}$/).join等于“ 75 22”(包括空格)。

现在我想用“ X”代替所有数字(而不是空格!),但是

phoneNumber.gsub(/\d.{4}$/, "X")

输出“ +36 6 41 88 X”,我希望我的代码输出“ +36 6 41 88 XX XX”。

我也尝试了以下麻烦的解决方案:

phoneNumber = "+36 6 41 88 75 22"
def anonymizer(phone)
    lastFour = phone.scan(/\d.{4}$/).join
    anonFour = lastFour.chars
    anonFour.each do |digit|
        digit.gsub(/[0-9]/, "X")
    end
    puts "attempted transform #{anonFour}"
    phone.gsub(lastFour, anonFour.join)
end


phoneyNumber = anonymizer(phoneNumber)
puts phoneyNumber 

无济于事,因为它按原样返回数字(“ +36 6 41 88 75 22”而不是“ +36 6 41 88 XX XX”)]

regex ruby string substitution
3个回答
0
投票

如果您的字符串仅包含以'dd dd'结尾的电话号码,其中d是数字,则不需要正则表达式:

'+36 6 41 88 75 22'[0..-6] + 'XX XX'
  #=> "+36 6 41 88 XX XX" 

但是,我认为对“最后四个数字字符”的解释更有趣,可以将连续的数字对分隔为零个或多个非数字。在这种情况下,以下是进行所需替换的简单方法。

def sub_last4(str)
  n = str.count('0123456789')
  str.gsub(/\d/) { |s| (n -= 1) <= 3 ? 'X' : s }
end

sub_last4 '+36 6 41 88 75 22'
  #=> "+36 6 41 88 XX XX" 
sub_last4 '+36 6 41 88 7522'
  #=> "+36 6 41 88 XXXX"
sub_last4 '+36 6 how 41 8 now 8 75 2 brown 5 cow'
  #=> "+36 6 how 41 8 now 8 XX X brown X cow"
sub_last4 'SY-0-6447'
  #=> "SY-0-XXXX"

这是第二种方式。

def sub_last4(str)
  4.times.each_with_object(str.dup) { |_,s|
    s[s.rindex(/\d/)] = 'X' }
end

3
投票

您可以使用

phoneNumber = phoneNumber.gsub(/\d(?=(?:\D*\d){0,3}\D*\z)/, 'X')

请参见regex demoonline Ruby demo

详细信息

  • [\d-一个数字...
  • (?=(?:\D*\d){0,3}\D*\z)-紧随其后
    • (?:\D*\d){0,3}-0至3次连续出现
      • \D*-0+个非数字字符
      • [\d-一个数字
    • \D*-0+个非数字字符
    • [\z-字符串的结尾($匹配Ruby正则表达式中的行的结尾)。

[另一个想法:将最后四个数字与除数字以外的任何字符匹配,然后仅将这些数字替换为X

phoneNumber.gsub(/(?:\d\D*){4}\z/) { $~[0].gsub(/\d/, 'X') }

请参见this Ruby demo

这里,(?:\d\D*){4}\z匹配四个连续出现的数字和字符串末尾的任何0+个非数字字符,并且$~[0]块中的gsub表示整个匹配值,其中.gsub(/\d/, 'X')替换每个X的数字。


0
投票

您几乎可以用自己的正则表达式\d.{4}$来获得它,但只需要进行两个小修改。

  1. 由于您想一次匹配一位数字并用X代替,因此您需要使用前瞻性(因为这不会消耗字符),因此一次一次只需要使用\d匹配一位数字即可。并将其更改为\d(?=.{4}$)

  2. 下一次,因为您要匹配最后四位数字,因此需要将{4}更改为{0,4},以便您的前瞻性说,匹配行尾之前有零到四个字符的数字。

并且具有这两个修改的新正则表达式将紧随其后,

\d(?=.{0,4}$)

将为您提供所需的结果。

See this demo

© www.soinside.com 2019 - 2024. All rights reserved.