validates_format_of :phone with => /^\([0-9]{3}\)[-. ]?[0-9]{3}[-. ]?[0-9]{4}|^[0-9]{3}[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/

Why doesn’t this phone validation work?

validates_format_of :phone, :with => /^([0-9]{3})[-. ]?[0-9]{3}[-. ]?[0-9]{4}|^[0-9]{3}[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/,

:message => “is not a phone number”

tested with (123) 456 7890

testing it here does work: but in a rails app, it fails validation except for 1234567890

In these situations I dramatically simplify until I get an expression
that does what I expect then build it back up to find the cause of the
failure. Since you seem to suggest that it is not working when
parentheses are included I would start with an expression that allows
(n) and work up from there.

Remember you can run it in the rails console so you do not need to
keep editing the app.


I’ve gone through about a couple of hours of building it up and tearing it down, I need someone else’s brain on this one please…

To be a bit more clear about how I see the problem: as I said earlier, validates the correctness of the expression, I’ve tried similar expressions in JS parsers, .NET parsers, Python parsers, they all pass, I think it’s the rails parsers that fails, and/or something about the validates with that doesn’t like the parenthesis… can someone prove me wrong? Please?

I have tested a simpler version and noticed this:

ruby-1.9.2-p136 :010 > /^(?[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/ =~ “1234567890”

=> 0

ruby-1.9.2-p136 :011 > /^(?[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/ =~ “(123)4567890”

=> 0

ruby-1.9.2-p136 :012 > /^(?[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/ =~ “(123) 456-7890”

=> 0

ruby-1.9.2-p136 :013 > /^(?[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/ =~ “(123)3456-7890”

=> nil

ruby-1.9.2-p136 :014 > /^(?[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/ =~ “(123)-456-7890”

=> 0

ruby-1.9.2-p136 :015 > /^(?[0-9]{3})?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/ =~ “(123) 456-7890 smurf”

=> nil

ruby-1.9.2-p136 :016 >

does 0 mean pass? And is then the validated_with not accepting 0 as a pass?

Hi Victor,

Bah! Much ado about nothing, I’m pretty sure now that the problem is that the database record only accepts integers for the phone column. I just checked the schema file, should have done that much earlier!

I do wish there was a different error message/exception raised if something like this happened rather than a failed validation, since validations ca be written to be independent of db column types and therefore not a reflection of what is acceptable to the database…

In your OP you said that you were using the :message option on the
validation. I would not have expected that message unless it was that
validation that failed. You can specify a different message for each
validation if you wish.


While I am guessing you've already solved your problem (because it was related to your database schema) I'll still answer your regular expression questions:

The number returned is the position of the string where your regular expression matches, 0 is the start of the string.
nil means no matches were found.

In the case of your regular expression you'd only ever get 0 or nil because your regular expression requires the start of the string to match.