【问题标题】:How to specify a range in Ruby如何在 Ruby 中指定范围
【发布时间】:2021-10-24 04:25:58
【问题描述】:

我一直在寻找一种查看项目字符串是否都是数字的好方法,并认为可能有一种方法可以指定从 0 到 9 的范围并查看它们是否包含在字符串中,但是我在网上查到的所有东西都让我很困惑。

def validate_pin(pin)
  (pin.length == 4 || pin.length == 6) && pin.count("0-9") == pin.length
end

上面的代码是别人的作品,我一直在尝试确定它是如何工作的。它是一个 pin 检查器 - 接受一组字符并确保字符串是 4 位或 6 位数字和所有数字 - 但范围是如何工作的?

当我做这个问题时,我尝试使用 to_a?整数和一堆其他的东西,包括范围如 (0..9) 和 ("0..9) 和 ("0".."9") 来验证一个字符是一个整数。当我看到 ("0 -9) 它把我弄糊涂了,半小时的谷歌搜索和 youtube 只给我留下了正则表达式教程(我对此很感兴趣,但目前只是想了解基础知识)

总而言之,我的目标是了解一种更语义/更简洁的方法来识别字符是否为整数。无论是最简单的方法。欢迎所有和任何反馈。我是一名新的红宝石学家,并试图了解我的基本面。谢谢。

【问题讨论】:

  • "....查看一串项目是否都是数字..." 不清楚。 "-24-12" 呢?我认为您的意思是,“....查看字符串是否仅包含数字 0-9”`。
  • 是的,这确实是我理解的目标
  • @DavidVenegas : _ 如果一个字符是一个整数_ : 你真的是指 一个字符,还是你的意思是 _ 一个字符串_?如果您引用字符串,您是否允许在前面加上 - 来表示否定?如果是,您是否允许在减号和第一个数字之间留有空格?请在您的问题中更具体一点。
  • @user1934428 我的问题应该很简单,但我有点忘乎所以。这就是我想要理解的。 问题: 通过用连字符分隔两个数字并用引号和括号括起来,你得到一个数组吗?我在问 ("0-9") 是否基本上是 [0,1,2,3,4,5,6,7,8,9]。

标签: ruby-on-rails ruby rspec rubygems rspec-rails


【解决方案1】:

正则表达式确实是做到这一点的正确方法。它专门用于测试字符串中的模式。这就是您如何测试“此字符串中的所有字符是否都在字符 0-9 的范围内?”:

pin.match(/\A[0-9]+\z/)

这个正则表达式说“这个字符串是否以至少一个字符 0-9 开始和结束,中间没有其他字符?” - \A 和 \z 是字符串开头和结尾匹配器,[0-9]+ 匹配该范围内的任何一个或多个字符。

您甚至可以在一行正则表达式中完成整个检查:

pin.match(/\A([0-9]{4}|[0-9]{6})\z/)

“这个字符串是由字符 0-9 恰好重复 4 次,还是字符 0-9 正好重复 6 次?”

Ruby 的String#count method 做了类似的事情,虽然它只是计算传递的字符的出现次数,并且它使用类似于正则表达式范围的东西来允许您指定字符范围。

序列c1-c2表示c1和c2之间的所有字符。

因此,它将参数“0-9”扩展为字符列表“0123456789”,然后测试字符串中有多少字符与该字符列表匹配。

这将用于验证字符串中是否存在一定数量的数字,并且长度检查让您可以隐式测试字符串中不存在 other 字符。但是,正则表达式可以让您直接断言,通过确保整个字符串匹配给定的模式,包括长度限制。

【讨论】:

  • 这是正确的答案,但您介意解释一下pin.count("0-9") 方法是否有效吗?
  • 我第二个@Mohammad,pin.count("0-9") 自己工作吗
  • 查看 String#count 的链接文档。
  • 一个小点,这么小我不确定它是否值得一提,但在这里:您可能想要使用非捕获(而不是捕获)组。每当我看到带有捕获组的正则表达式时,我都希望稍后会引用捕获组的内容。像这里一样,当我发现内容没有被引用时,我意识到我刚刚浪费了数百毫秒的时间来思考它。这足以毁掉一个人的一天。
【解决方案2】:

计算pin 中的所有非数字并检查该计数是否为零:

pin.count("^0-9").zero?

【讨论】:

    【解决方案3】:

    由于您似乎在寻找正则表达式之外的答案,并且由于 Chris 已经在上面的示例中说明了 count 方法是如何实现的,所以我将尝试添加另一个想法来测试字符串是否为 Integer :

    pin.to_i.to_s == pin
    

    我们正在做的是将字符串转换为整数,将结果转换回字符串,然后测试在此过程中是否有任何变化。如果结果是=>true,那么您知道在转换为整数期间没有任何变化,因此字符串只是一个整数。

    编辑: 上面的示例仅适用于整个字符串是整数并且不能正确处理前导零的情况。如果您想检查以确保每个字符都是整数,请改为执行以下操作:

    pin.prepend(“1”).to_i.to_s(1..-1) == pin
    

    【讨论】:

    • 这很有创意,虽然可能不是最佳实践(必须学习正则表达式)谢谢 Micheal
    • 我同意使用正则表达式可能是最合乎逻辑的解决方案,因为它们明确说明了它们的目的并完全按照预期使用。另一方面,我的解决方案并没有提供很多关于其目的的线索。请记住,尽管从计算上讲,正则表达式通常被认为要慢得多,因此使用它们并不全是玫瑰。我个人觉得它们也极难阅读,我个人认为根据应用程序值得考虑。
    【解决方案4】:

    部分问题似乎正是以下部分代码是如何工作的:

    pin.count("0-9")
    

    这段代码只是返回字符串中存在多少个数字 0 到 9 的实例的计数。不过,这只是相关代码部分的一部分。您需要查看该行的其余部分才能理解它:

    pin.count("0-9") == pin.length
    

    第一部分计算有多少实例,然后第二部分将其与字符串的长度进行比较。如果它们相等(==),则意味着字符串中的每个字符都是整数。

    【讨论】:

    • 是的,谢谢你澄清这一点,但我真正的问题是 ("0-9") 是否是一个数组。我认为它就像一个字符串,我不能让我的 .count 枚举来计算它。是 ("0-9") 和数组吗?
    • “0-9”既不是字符串也不是数组。它是一个参数列表(有点像一个参数)。
    【解决方案5】:

    有时可以使用否定来获得优势:

    !pin.match?(/\D/) && [4,6].include?(pin.length)
    

    pin.match?(/\D/)返回true,如果字符串包含一个数字以外的字符(匹配/\D/),在这种情况下它将被否定为false

    在这里使用否定的一个优点是,如果字符串包含除数字以外的字符,pin.match?(/\D/) 将在找到非数字后立即返回 true,这与检查字符串中所有字符的方法相反。字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      相关资源
      最近更新 更多