2012-01-07 45 views
1

我写了一个正则表达式来帮助验证游戏角色名称的字符串。它以某种方式传递看起来无效的字符串,而不是传递看起来有效的字符串。Ruby on Rails中的这个正则表达式有什么问题?

要求:

  • 开始用大写字母
  • 之后还会有任意数量的字母数字字符(包括空格)

这是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中测试了它,它的工作方式与您所期望的相同。

什么给?

谢谢你的帮助!

回答

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

这是否适当地禁止换行符?一些谷歌命中暗示,在Ruby中,'^'和'$'默认为“开始行”和“行结束”(像其他语言的多行模式正则表达式),所以您需要使用'\ A'和'\ z'表示“字符串开始”和“结束字符串”。 (我自己没有测试过。) – ruakh 2012-01-07 04:12:23

+0

O.K.,没关系,我看你现在已经明白了。 +1。 :-) – ruakh 2012-01-07 04:13:08

+0

急于得到答案,我忘记了这个问题。 :) – jergason 2012-01-07 04:14:22

0

如果你只想在字符串的开头匹配大写字母,你需要把在“行首”标志^所以它看起来像:

validates :name, format: { with: %r{^[A-Z][a-zA-Z0-9\s]*} } 

退房Rubular到玩你的正则表达式

+0

Rubular实际上是我测试这个问题的答案的地方。 :)伟大的资源。 – jergason 2012-01-07 04:14:49

+0

感谢您的帮助! – Jamornh 2012-01-07 04:21:59

+0

没问题。尽管如此,但Jergason's正是你所需要的。祝你好运! – jstim 2012-01-07 04:35:23

相关问题