0

我需要按照我的模型中的以下格式验证输入证据编号。

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

4

4 回答 4

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中使用\Aand\z而不是^and 。$

如果您需要连字符后的“至少三位”,那么您需要:

/\A[A-z a-z]{3}-\d{3,}\z/

肯尼格兰特是对的,角色类中的空间看起来很奇怪。

于 2012-08-29T20:25:08.003 回答
1

尝试添加^开头和$结尾。

validates_format_of :evidence_number, :with=> /^[A-Za-z]{3,4}-\d{3,6}$/

不过使用mu is too short's 的答案。

于 2012-08-29T19:59:22.370 回答
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/
于 2012-08-29T20:34:24.043 回答
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 
于 2012-08-29T19:58:49.763 回答