我需要在我的模型中按照以下格式验证输入证据编号。
XXX-###
XXX-####
XXX-#####
XXX-######
XXXX-#####
XXXX是字母,####是数字
我的模型代码中有以下内容。
validates_format_of :evidence_number, :with=> /[A-Z a-z]{3}-\d{3,6}/
它仅适用于小于3的数字,即它适用于XXX-12但不适用于超过6的数字,即它不适用于XXX-1234567
答案 0 :(得分:3)
你应该使用\A
(字符串的开头)和\z
(字符串的结尾)锚,而不是^
(行的开头)和$
(结束) ():
validates_format_of :evidence_number, :with=> /\A[A-Z a-z]{3}-\d{3,6}\z/
一个简单的例子将说明不同之处:
>> "wrong\nXXX-999\nanchors" =~ /^[A-Z a-z]{3}-\d{3,6}$/
=> 6
>> "wrong\nXXX-999\nanchors" =~ /\A[A-Z a-z]{3}-\d{3,6}\z/
=> nil
>> "XXX-999" =~ /^[A-Z a-z]{3}-\d{3,6}$/
=> 0
>> "XXX-999" =~ /\A[A-Z a-z]{3}-\d{3,6}\z/
=> 0
您几乎总是希望在Ruby中使用\A
和\z
代替^
和$
。
如果在连字符后需要“至少三位数”,则需要:
/\A[A-z a-z]{3}-\d{3,}\z/
并且Kenny Grant是正确的,字符类中的空格看起来很奇怪。
答案 1 :(得分:1)
尝试添加^
开头和$
结尾。
validates_format_of :evidence_number, :with=> /^[A-Za-z]{3,4}-\d{3,6}$/
尽管使用mu is too short
的答案。
答案 2 :(得分:1)
您可能最好设置一些测试代码,并单独测试正则表达式(或理想情况下设置单元测试并以此方式进行测试)。
invalid = %w[777-2345 ABCD-12 ABCD-12345678 AB-12345678 ABC-1234567]
valid = %w[ABC-12345 ABCD-123 ABCD-1234 ABCD-12345 ABCD-123456]
def validate codes,regex
codes.each do |code|
if code =~ regex
puts "Valid code #{code}"
else
puts "Invalid code #{code}"
end
end
end
使用正则表达式测试上述内容时,会出现一些问题。根据您的描述,我不明白为什么您的正则表达式将空格包含为允许的字符 - 对于代码,这似乎不太可能是有效的代码。所以你可能会用这样的东西做得更好:
/\A[A-Za-z]{3,4}-\d{3,6}\z/
将匹配限制为完整字符串,并将第一个匹配限制为3或4个字母字符,最终匹配限制为3-6个数字。这假设####在您的示例中不是错误的:
puts "\n\nUSING NEW REGEX"
puts "Validating valid codes"
validate valid,/\A[A-Za-z]{3,4}-\d{3,6}\z/
puts "\nValidating INVALID codes"
validate invalid,/\A[A-Za-z]{3,4}-\d{3,6}\z/
答案 3 :(得分:0)
添加字符串开头和结尾的正则表达式字符:
validates_format_of :evidence_number, :with=> /^[A-Z a-z]{3}-\d{3,6}$/
ruby-1.9.3-p125 :000 > "ABC-1234567".match /[A-Z a-z]{3}-\d{3,6}/
=> #<MatchData "ABC-123456">
ruby-1.9.3-p125 :001 > "ABC-1234567".match /^[A-Z a-z]{3}-\d{3,6}$/
=> nil