我一直在寻找一种好方法来查看一串项目是否都是数字,并认为可能有一种方法可以指定从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只给我留下了正则表达式教程(我对它很感兴趣,但目前只是试图获得基础知识)
所以总结一下,我的目标是理解一种更语义/简洁的方法来识别一个字符是否是整数。用最简单的方法。欢迎所有和任何反馈。我是一个新的红宝石爱好者,并试图得到我的基础。谢谢你。
Regex确实是做到这一点的正确方法。它专门用于测试字符串中的模式。以下是测试"此字符串中的所有字符是否都在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方法做了类似的事情,尽管它只是计算传递的字符的出现次数,并且它使用类似于regex范围的东西来允许您指定字符范围。
c1-c2表示c1和c2之间的所有字符。
因此,展开参数"0-9"插入字符列表"0123456789",然后测试字符串中有多少个字符与该字符列表匹配。
这将用于验证字符串中是否存在一定数量的数字,并且长度检查允许您隐式地测试字符串中是否存在其他字符。然而,正则表达式允许您直接断言,通过确保整个字符串匹配给定的模式,包括长度约束。
计算pin
中所有非数字并检查该计数是否为零:
pin.count("^0-9").zero?
既然你似乎在寻找regex之外的答案,并且既然Chris已经在上面的例子中说明了count方法是如何实现的,我将尝试添加一个测试字符串是否为Integer的想法:
pin.to_i.to_s == pin
我们所做的是将字符串转换为整数,将结果转换回字符串,然后测试在此过程中是否有任何更改。如果结果是=>true
,那么你知道在转换成整数的过程中没有任何变化,因此字符串只是一个整数。
编辑:上面的例子只有在整个字符串是Integer并且不能正确处理前导零的情况下才有效。如果你想检查确保每个字符都是整数,那么你可以这样做:
pin.prepend(“1”).to_i.to_s(1..-1) == pin
部分问题似乎是下面这部分代码是如何完成它的工作的:
pin.count("0-9")
这段代码只是返回一个计数,表示在字符串中有多少个数字0到9的实例。不过,这只是相关代码的一部分。您需要查看该行的其余部分来理解它:
pin.count("0-9") == pin.length
第一部分计算实例的数量,然后第二部分将其与字符串的长度进行比较。如果它们相等(==
),则意味着字符串中的每个字符都是整数。
有时否定可以发挥作用:
!pin.match?(/D/) && [4,6].include?(pin.length)
pin.match?(/D/)
如果字符串包含数字以外的字符(匹配/D/
),则返回true
,在这种情况下,它将被反化为false
。
在这里使用否定的一个优点是,如果字符串包含非数字字符,则pin.match?(/D/)
将在找到非数字字符时立即返回true
,而不是检查字符串中的所有字符。