Ruby 如果只输入零,则从字符串中删除多个零

Ruby 如果只输入零,则从字符串中删除多个零,ruby,Ruby,我试图实现一种方法,如果用户输入一系列零,比如“00000”,它应该返回“0” 否则,如果用户输入例如“00009”或“90000”,则输入变量应保持不变 这个问题有简单的解决方法吗?试试这个 "0000000".gsub(/^0+$/, '0') => "0" "0000009".gsub(/^0+$/, '0') => "0000009" => "0" "

我试图实现一种方法,如果用户输入一系列零,比如
“00000”
,它应该返回
“0”

否则,如果用户输入例如
“00009”
“90000”
,则输入变量应保持不变

这个问题有简单的解决方法吗?

试试这个

"0000000".gsub(/^0+$/, '0')
 => "0" 
"0000009".gsub(/^0+$/, '0')
 => "0000009" 
 => "0" 
"9000000".gsub(/^0+$/, '0')
 => "9000000" 

可以使用正则表达式执行此操作,如下所示:

def验证_序列(序列:)
r=/\A(^0+[1-9]+\z)|(\A[1-9]+[0-9]+\z)/
序列匹配?(r)?序列:“0”
结束
如果序列与正则表达式或0匹配,则上述代码返回相同的序列。在另一种情况下,正则表达式验证序列是否为有效数字,或者如果以有效数字序列结尾,则double
更改
match
函数的结果并返回布尔值

您可以按如下方式使用上面的代码:
validate\u sequence(sequence:'0000000')

如果只想在开头和结尾匹配不同于0的数字,可以通过如下方式更改r的值:
r=/(^0+[1-9]+$)|(^[1-9]+0+$)/


请参阅文档的最后一句。

当字符串始终仅包含数字时,您可能需要考虑:

sequence.to_i.zero? ? '0' : sequence

当有这么多不同的解决方案时,运行基准测试总是很有趣的

require 'benchmark/ips'

Benchmark.ips do |x|
  examples = %w[00000 00001 12345]

  def cary_swoveland(str)
    str.squeeze == '0' ? '0' : str
  end

  def r4cc00n(str)
     r = /(^0+[1-9]+$)|(^[1-9]+[0-9]+$)/
     !!str.match(r) ? str : '0'
  end

  def spickermann(str)
    str.to_i.zero? ? '0' : str
  end

  def ursus(str)
    str.gsub(/^0+$/, '0')
  end

  %w[cary_swoveland r4cc00n spickermann ursus].each do |algorithm|
    x.report(algorithm) { examples.each { |e| send(algorithm, e) } }
  end

  x.compare!
end
结果:

$ ruby benchmark.rb 
Warming up --------------------------------------
      cary_swoveland    86.149k i/100ms
             r4cc00n    24.258k i/100ms
         spickermann    94.211k i/100ms
               ursus    21.714k i/100ms
Calculating -------------------------------------
      cary_swoveland    833.459k (± 2.2%) i/s -      4.221M in   5.067333s
             r4cc00n    231.787k (± 6.9%) i/s -      1.164M in   5.050636s
         spickermann    905.658k (±10.0%) i/s -      4.522M in   5.097849s
               ursus    213.674k (± 2.3%) i/s -      1.086M in   5.083811s

Comparison:
         spickermann:   905658.0 i/s
      cary_swoveland:   833459.1 i/s - same-ish: difference falls within error
             r4cc00n:   231787.4 i/s - 3.91x  (± 0.00) slower
               ursus:   213674.2 i/s - 4.24x  (± 0.00) slower

很好@Cary Swoveland考虑到
“x00”。对于_i#=>0
,您只依赖于包含数字的字符串(如示例中所示)。我不是说这不是一个合理的假设,而是认为它值得一提。我运行了你的基准测试,发现在我第143次尝试中,
cary\u swoveland
是最快的。注意
validate\u序列(序列:“010”)#=>“0”
。我的理解是,只有当字符串中的所有字符都为零时,才会返回
“0”
。关于正则表达式,捕获组没有任何用途,虽然这里的线端锚(
^
$
)可以,但通常建议使用线端锚(
\A
\z
)来锚定字符串。你不需要
作为
!!sequence.match(r)
false
当且仅当
sequence.match(r)#=>nil
(因此falsy,与truthy相反)<代码>序列。匹配?(r)?序列:“0”
可能更具表现力。对于好的评论@Cary Swoveland,虽然我不清楚“010”是一个有效字符串,但从我的理解和公平性来看,在问题中并不清楚,此外,我同意
更具表现力,我将用它编辑我的答案,关于锚,我不知道thx的好建议
require 'benchmark/ips'

Benchmark.ips do |x|
  examples = %w[00000 00001 12345]

  def cary_swoveland(str)
    str.squeeze == '0' ? '0' : str
  end

  def r4cc00n(str)
     r = /(^0+[1-9]+$)|(^[1-9]+[0-9]+$)/
     !!str.match(r) ? str : '0'
  end

  def spickermann(str)
    str.to_i.zero? ? '0' : str
  end

  def ursus(str)
    str.gsub(/^0+$/, '0')
  end

  %w[cary_swoveland r4cc00n spickermann ursus].each do |algorithm|
    x.report(algorithm) { examples.each { |e| send(algorithm, e) } }
  end

  x.compare!
end
$ ruby benchmark.rb 
Warming up --------------------------------------
      cary_swoveland    86.149k i/100ms
             r4cc00n    24.258k i/100ms
         spickermann    94.211k i/100ms
               ursus    21.714k i/100ms
Calculating -------------------------------------
      cary_swoveland    833.459k (± 2.2%) i/s -      4.221M in   5.067333s
             r4cc00n    231.787k (± 6.9%) i/s -      1.164M in   5.050636s
         spickermann    905.658k (±10.0%) i/s -      4.522M in   5.097849s
               ursus    213.674k (± 2.3%) i/s -      1.086M in   5.083811s

Comparison:
         spickermann:   905658.0 i/s
      cary_swoveland:   833459.1 i/s - same-ish: difference falls within error
             r4cc00n:   231787.4 i/s - 3.91x  (± 0.00) slower
               ursus:   213674.2 i/s - 4.24x  (± 0.00) slower