0

我有一个文本字段,它只接受满足以下条件的文本:

以下类型的文本格式,其中“A”可以是任何随机字母,“D”是任何数字,但最后一位是所有其他数字的模 10 的总和。

AAD-AAA-DDD

例如:

KN3-MNO-41_, this means the last digit is: 3 + 4 + 1 = 8, so it becomes: KN3-MNO-418
HK5-SFO-32_, this means the last digit is: 5 + 3 + 2 = 10, so it becomes HK5-SFO-320

我正在初步学习 ruby​​,请帮助我:那么我如何在脚本中包含这些检查并验证输入文本是否符合标准。

谢谢

4

2 回答 2

1
def valid?(w)
   w.match(/^[a-z][a-z]\d-[a-z][a-z][a-z]-\d\d\d$/i) and
   ([2,8,9].sum {|i| w[i].to_i} % 10 == w[10].to_i)
end
于 2013-05-21T23:57:04.247 回答
1

这是一个疯狂的打击:

REGEX = /^([a-z]{2})(\d)-([a-z]{3})-(\d)(\d)(\d)$/i
STRINGS = %w[
  KN3-MNO-418
  HK5-SFO-320
  KN3-MNO-419
  HK5-SFO-321
]

def valid?(str)
  chars1, d1, chars2, d2, d3, chksum = REGEX.match(str).captures
  ([d1, d2, d3].map(&:to_i).inject(:+) % 10) == chksum.to_i
end

STRINGS.each do |s|
  puts valid?(s)
end

运行输出:

true
true
false
false

为了乐趣和利润,您可以将match作业更改为:

_, d1, _, d2, d3, chksum = REGEX.match(str).captures

和/或计算:

([d1, d2, d3].inject(0) { |m, s| m += s.to_i } % 10) == chksum.to_i

现在,这肯定会让你和我一样感到困惑,所以我将把它分解:

  • /^([a-z]{2})(\d)-([a-z]{3})-(\d)(\d)(\d)$/i方法:
    1. 从字符串的开头开始,找到“a”..“z”之间的两个字符,然后是...
    2. 一个数字,后跟...
    3. 一个连字符,后跟...
    4. “a”..“z”之间的三个字符,后跟另一个连字符和...
    5. 两个单独的数字和校验和数字。
  • REGEX.match(str).captures将模式与字符串匹配。captures从字符串中返回一个捕获值的数组。“捕获”是括号之间的模式中的部分。
  • 的结果captures并行分配给局部变量。甜的。
  • ([d1, d2, d3].map(&:to_i).inject(:+) % 10) == chksum.to_i是让我们“哇哇哇!!!”的部分:
    1. [d1, d2, d3].map(&:to_i)将字符串数组转换为整数数组...
    2. inject(:+)是“将数组的所有元素加在一起”的 Ruby 魔法。...
    3. % 10modulo 10。查找 modolo,这是您的新朋友。
    4. 其余的你可以弄清楚。
于 2013-05-22T01:03:47.037 回答