Hello all After being told of a funky date validator I will ask again for another validator :) Does anyone know of a plugin that validates that a field is the correct syntax for an IP Address? Thanks Jeff -- Posted via http://www.ruby-forum.com/.
A good start is to use validates_format_of. This is probably close to what you need: validates_format_of :ip_address, :with => /^(\d{1,3}\.){3}\d{1,3}$/ You could do more validation to check that it''s a valid ip, it shouldn''t be too hard. -Jonny. On 4/18/06, Jeff Jones <rurounijones@hotmail.com> wrote:> > Hello all > > After being told of a funky date validator I will ask again for another > validator :) Does anyone know of a plugin that validates that a field is > the correct syntax for an IP Address? > > Thanks > > Jeff > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060418/f48b21fd/attachment.html
Jonathan Viney wrote:> A good start is to use validates_format_of. This is probably close to > what > you need: > > validates_format_of :ip_address, :with => /^(\d{1,3}\.){3}\d{1,3}$/ > > You could do more validation to check that it''s a valid ip, it shouldn''t > be > too hard. > > -Jonny.Hmm good point. My regexp-fu is non-existant but I suppose I have to learn it sooner or later. Cheers Jeff -- Posted via http://www.ruby-forum.com/.
Jeff Jones wrote:> Jonathan Viney wrote: >> A good start is to use validates_format_of. This is probably close to >> what >> you need: >> >> validates_format_of :ip_address, :with => /^(\d{1,3}\.){3}\d{1,3}$/ >> >> You could do more validation to check that it''s a valid ip, it shouldn''t >> be >> too hard. >> >> -Jonny. > > Hmm good point. My regexp-fu is non-existant but I suppose I have to > learn it sooner or later. > > Cheers > > JeffOr I could be a cheezy bugger and scrib around the net for an example: \b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b -- Posted via http://www.ruby-forum.com/.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Jeff,> Or I could be a cheezy bugger and scrib around the net for an example: > > \b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]? > [0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2 > [0-4][0-9]|[01]?[0-9][0-9]?)\bHere''s a shorter regexp that validates an IP: /\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5]|(?:2[0-4]|1 \d|[1-9])?\d)){3}\z/ It looks kinda crazy, but you''ll notice that its basically the same segment twice. The second time the segment is seen, it ensures that there is a leading "." in front, and that the segment should be repeated {3} times. The (?: and ) are basically the same as ( and ), the difference is they just group stuff together without capturing the matching strings into $1, $2, $3, etc, which saves a bit of memory. Its also slightly stricter in that it won''t allow a "segment" to start with a leading 0 (like 10.0.01.0) as the longer one above allows, although it will allow IPs with zeros "on their own", like 10.0.0.0 You may even want to see if the IP address falls into one of the "special" address blocks that are reserved for specific usage as defined in RFC 3330: http://rfc.net/rfc3330.html Depending on your app it might make sense to disallow some (all?) of these IPs. - -- Thanks, Dan __________________________________________________________________ Dan Kubb Autopilot Marketing Inc. Email: dan.kubb@autopilotmarketing.com Phone: 1 (604) 820-0212 Web: http://autopilotmarketing.com/ vCard: http://autopilotmarketing.com/~dan.kubb/vcard __________________________________________________________________ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (Darwin) iD8DBQFERRF44DfZD7OEWk0RAhtJAKCcTel3Nawie/atJrlQHDuGiXt3TgCglKbv d9CPfWWC0vdwKy//kVSLpuY=sHod -----END PGP SIGNATURE-----
> Here''s a shorter regexp that validates an IP: > > /\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5]|(?:2[0-4]|1 > \d|[1-9])?\d)){3}\z/ > > It looks kinda crazy, but you''ll notice that its basically the same > segment twice. The > second time the segment is seen, it ensures that there is a leading > "." in front, and > that the segment should be repeated {3} times. The (?: and ) are > basically the same > as ( and ), the difference is they just group stuff together without > capturing the > matching strings into $1, $2, $3, etc, which saves a bit of memory. > > Its also slightly stricter in that it won''t allow a "segment" to > start with a leading > 0 (like 10.0.01.0) as the longer one above allows, although it will > allow IPs with > zeros "on their own", like 10.0.0.0 > > You may even want to see if the IP address falls into one of the > "special" address > blocks that are reserved for specific usage as defined in RFC 3330: >Thanks very much for the more efficient regexp (I am suprised that this along with date validation isn''t included as part of Activerecord::Base validation types). I don''t need to validate down to the "Is it one of the special IP blocks" as network pros (hopefully) will be entering this data and it is only for display, not processing so I just wanted to avoid the most basic problems (typos and the like) Thank yo very much! (Gawd I love this forum. ) Jeff -- Posted via http://www.ruby-forum.com/.
Hmm, trying to plug that into the validation produces the following error, with a REGEXP this complex I wouldn''t know where to start, sorry if I am missing something very basic: vendor/rails/activesupport/lib/active_support/dependencies.rb:140:in `load'': ./app/models/server.rb:6: premature end of regular expression: /^(/ app/models/server.rb:6: parse error, unexpected $undefined., expecting kEND validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i ^ app/models/server.rb:6: parse error, unexpected tINTEGER, expecting '')'' validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i ^ app/models/server.rb:6: parse error, unexpected tINTEGER, expecting '')'' validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i ^ app/models/server.rb:6: parse error, unexpected $undefined., expecting '')'' validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i ^ app/models/server.rb:6: parse error, unexpected $undefined. validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i ^ app/models/server.rb:6: parse error, unexpected '')'', expecting kEND validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i ^ app/models/server.rb:6: parse error, unexpected $undefined., expecting '')'' validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i ^ app/models/server.rb:6: parse error, unexpected $undefined. validates_format_of :ipaddress, :with => /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/)$/i -- Posted via http://www.ruby-forum.com/.
Hi Jeff,> Hmm, trying to plug that into the validation produces the following > error, with a REGEXP this complex I wouldn''t know where to start, > sorry > if I am missing something very basic:I forgot that I''m using an alternate Regexp engine to get a slightly richer set of matching options. I''ll rework the Regexp to work with all versions of Ruby and get back to you. -- Dan
I am not sure this will work in ruby, but it works for me with libpcre. This regex validates both IPv4 and IPv6 ipaddresses. Some tweaking may be needed. ((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})
Hi Jeff,> Hmm, trying to plug that into the validation produces the following > error, with a REGEXP this complex I wouldn''t know where to start, > sorry > if I am missing something very basic: > > vendor/rails/activesupport/lib/active_support/dependencies.rb:140:in > `load'': ./app/models/server.rb:6: premature end of regular expression: > /^(/ > app/models/server.rb:6: parse error, unexpected $undefined., expecting > kEND > validates_format_of :ipaddress, :with => > /^(/\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5])|(?:2[0-4]| > 1\d|[1-9])?\d)){3}\z/)$/iI just tested the Regexp out on another machine with a "stock" version of Ruby, and the Regexp did work. I think you might''ve added a few things to the Regexp that caused it to be invalid -- you''ve missed the purpose behind "\A" and "\z". Here''s a snippet from my favorite regexp reference, perl''s "perlre" (yeah I know its not a ruby document, but I think the documentation on Regexps is better in perl than ruby, and while there are small differences, they are fairly similar in the simple cases): The "\A" and "\Z" are just like "^" and "$", except that they won''t match multiple times when the "/m" modifier is used, while "^" and "$" will match at every internal line boundary. To match the actual end of the string and not ignore an optional trailing newline, use "\z". IMHO most of the time people use "^" and "$" when they really mean "\A" and "\z", but they just don''t know about them. Can you try the following on your machine and see if it works for you: validates_format_of :ipaddress, :with => /\A(?:25[0-5]|(?:2[0-4]|1 \d|[1-9])?\d)(?:\.(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/ If this doesn''t work, what version of ruby are you using? -- Dan
> Can you try the following on your machine and see if it works for you: > > validates_format_of :ipaddress, :with => /\A(?:25[0-5]|(?:2[0-4]|1 > \d|[1-9])?\d)(?:\.(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/ > > If this doesn''t work, what version of ruby are you using? > > -- > > DanThat line of code works (I am on Rails 1.1.2). Thanks very much. -- Posted via http://www.ruby-forum.com/.