【问题标题】:Ruby determine if a string only contains numbersRuby判断一个字符串是否只包含数字
【发布时间】:2014-06-18 10:15:18
【问题描述】:

我正在尝试创建一种要求用户创建密码的方法,例如银行帐户密码。长度只能是4个数字,输入的每个字符都必须是数字。我在使用这段代码时发现:

puts "Please give us a 4 digit pin number for your account:"
@response = gets.chomp 

unless @response.to_i.is_a?(Integer) && @response.to_str.length == 4
    puts "Your response must be 4 numbers in length."
    create_pin
else
    @pin = @response.to_i
    puts "Your pin has been set."
end

它不像我希望的那样工作,因为 .to_i 方法很乐意将 '2134a' 转换为 2134。同样,如果字符串中没有 Integer,它会将值记录为 0,这不是 false我需要它。

Test if a string is basically an integer in quotes using Ruby?

我发现了一个非常有用的帖子,但它似乎在对正则表达式的线程执行中变得相当复杂。这个帖子也被关闭了,因为作者不够具体:

Check if string contains only positive numbers in Ruby

所以我会尽量清楚,我试图限制用户输入,以便他们只能输入数字 0 到 9。像 10^3 这样的数学方程需要失败,以及像 -1234 这样的负数,并且我试图将它们限制为四位数,就像限制任何引脚的方式一样。到目前为止,我完全被难住了,还没有看到不包含一大堆正则表达式的方法。

也许我可以检查字符串是否包含不可接受的字符列表。

先谢谢了。

为了更好的措辞和纠正我在第二段中写的错误而进行了编辑。

【问题讨论】:

  • 这是一个微不足道的正则表达式。就个人而言,我建议您花更多时间尝试弄清楚,或者向我们展示您的尝试。没有比这更容易的了,而且很容易搜索。
  • 老实说,我不知道如何使用正则表达式。我想知道是否有像数字这样的特定方法? (这没有用)我可以运行,但我想我迟早要学习正则表达式。另外,我永远不知道我发布的代码是太多还是太少。我应该保持主题,但我永远不知道主题是什么,因为我的许多错误都与语法有关。
  • "它将值记录为 nil,这不是我需要的错误。"只是为了澄清nilfalse 实际上是红宝石中唯一的false。您的问题不是nil,而是以非数字字符开头的String 将在调用to_i 时返回0。您是说将此字符串转换为Integer,然后询问这是Integer。答案当然是因为你刚刚成功了。
  • 任何开发人员都必须具备正则表达式技能。
  • 所以我注意到了。 wvandaal 和 hbejgel 都将我与 Rubular 联系起来。对于初学者来说,这似乎是一个很好的资源。另外,engineersmnky 你是对的,我的意思是输入 0 而不是 nil。当所有仅使用字母的引脚实际通过并保存为 0 时,我发现了这个问题。我将进行编辑以修复它。

标签: ruby regex string integer


【解决方案1】:

试试这个:

def valid_pin?(pin)
  /^\d{4}$/ === pin
end

这基本上是在说:

  1. /^d{4}$/ 是一个正则表达式,你可以看出来,因为它被 / / 包围,中间有一个模式
  2. ^$ 字符分别表示字符串的开头和结尾。基本上可以确保不接受具有 4 个连续数字但开头或结尾有其他字符的字符串(即"a1234""5678b")。
  3. \d 是表示数字的正则表达式字符。当后面跟着{4} 时,这意味着要查找正好 4 位数字。 Ruby 还允许您使用此符号 {3,} 或范围 {3,6} 指定最小值。
  4. === 方法(正如 @iamnotmaynard 正确提到的),有时称为 threequals 运算符,返回一个布尔值(truefalse)取决于正则表达式是否匹配给定的字符串。

在您的代码上下文中:

puts "Please give us a 4 digit pin number for your account:"
@response = gets.chomp 

unless valid_pin?(@response)
  puts "Your response must be 4 numbers in length."
  create_pin
else
  @pin = @response.to_i
  puts "Your pin has been set."
end

如果您想尝试并了解正则表达式(通常称为 RegExes),我建议您在很棒的网站Rubular 上玩耍,这里有一个通用关键字列表和 RegEx 沙箱,可以帮助您向您的创作。

【讨论】:

  • 这是正确的正则表达式。如果您使用Regexp#===,您可以简化命令并避免略显老套的!!(因为它返回布尔值):/^\d{4}$/ === "1234" => true
【解决方案2】:

这可以使用正则表达式在几行中完成。像下面这样的东西应该可以完成它。

if @response =~ /^\d{4}$/
   @pin = @response
else
   puts "Your pin must be 4 numbers in length."
   create_pin
end

在正则表达式中,'^' 和 '$' 分别表示字符串的开始和结束。添加这些保证您在要查找的 4 位数字之前或之后不会有垃圾。因此,您避免使用诸如“1234a”之类的答案

“\d{4}”将匹配 4 个连续的数字 0-9。

因此,您已将用户范围缩小到仅响应“3421”、“9843”等。

【讨论】:

    【解决方案3】:

    你应该尝试使用正则表达式:

    unless /[0-9]{4}/.match(@response).to_s.length == 4 && @response.length == 4 
        puts "Your response must be 4 numbers in length."
        create_pin
    else
        @pin = /[0-9]{4}/.match(@response).to_s.to_i
        puts "Your pin has been set."
    end
    

    你可以在这个网站上玩弄正则表达式:http://rubular.com/

    【讨论】:

      【解决方案4】:

      以下将起作用:

      puts "Please give us a 4 digit pin number for your account:"
      @response = gets.chomp 
      
      unless @response.match(/\d{4}/) && @response.length == 4
        puts "Your response must be 4 numbers in length."
        create_pin
      else
        @pin = @response.to_i
        puts "Your pin has been set."
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-05
        • 2020-08-26
        • 1970-01-01
        相关资源
        最近更新 更多