我写了一个正则表达式来帮助验证游戏角色名称的字符串。它以某种方式传递看似无效的字符串,而不是传递看似有效的字符串。
要求:
这是在字符模型中进行验证的rails代码:
validates :name, format: { with: %r{[A-Z][a-zA-Z0-9\s]*} }
这是我正在使用的单元测试
test "character name should be properly formatted and does not contain any special characters" do
character = get_valid_character
assert character.valid?
character.name = "aBcd"
assert character.invalid?, "#{character.name} should be invalid"
character.name = "Number 1"
assert character.valid?, "#{character.name} should be valid"
character.name = "McDonalds"
assert character.valid?, "#{character.name} should be valid"
character.name = "Abcd."
assert character.invalid?, "#{character.name} should be invalid"
character.name = "Abcd%"
assert character.invalid?, "#{character.name} should be invalid"
end
问题: 正则表达式不传递“aBcd”,“Abcd。”和“Abcd%”。现在,我知道这是有效的,因为我在Python中测试了它,它的工作方式与您期望的一样。
是什么给出了?
感谢您的帮助!
答案 0 :(得分:6)
正则表达式在给定字符串中的任何位置查找匹配项,除非另有说明。
因此测试字符串'aBcd'
无效,但它包含一个有效的子字符串:'Bcd'
。与'Abcd%'
相同,其中有效子字符串为'Abcd'
。
如果要匹配整个字符串,请将其用作正则表达式:
# \A matches string beginning, \z matches string end
%r{\A[A-Z][a-zA-Z0-9\s]*\z}
PS:有些人会说要将字符串的开头与^
匹配,而将结尾与$
匹配。在Ruby中,这些符号匹配行的开头和结尾,而不是字符串。因此,如果您使用"ABCD\n%"
和^
,$
仍会匹配,但如果您使用\A
和\z
则不匹配。有关详情,请参阅Rails security guide。
答案 1 :(得分:0)
如果您只想匹配字符串开头的大写字母,则需要输入“行首”标记^
,如下所示:
validates :name, format: { with: %r{^[A-Z][a-zA-Z0-9\s]*} }
查看Rubular以使用正则表达式