2011-06-03 28 views
5

Estoy tratando de usar una expresión regular para validar el formato de un nombre de dominio en mi modelo de Rails. Probé la expresión regular en Rubular con el nombre de dominio http://trentscott.com y coincidió.Ruby on Rails Validación del nombre de dominio (regex)

Cualquier idea de por qué falla la validación cuando la pruebo en mi aplicación Rails (dice "el nombre no es válido").

Código:

domain_regex = /^((http|https):\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$/ix 

    validates :serial, :presence => true 
    validates :name, :presence => true, 
        :format => { :with => domain_regex } 

Respuesta

6

Su entrada (http://trentscott.com) no tiene un subdominio pero la expresión regular es la comprobación de uno.

domain_regex = /^((http|https):\/\/)[a-z0-9]*(\.?[a-z0-9]+)\.[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$/ix 

actualización

También no necesita el? after ((http | https): \/\ /) a menos que a veces falte el protocolo. También he escapado. porque eso coincidirá con cualquier personaje. No estoy seguro de lo que el grupo de arriba es para, pero aquí es una versión mejor que soporta los guiones y los grupos por la sección

domain_regex = /^((http|https):\/\/) 
(([a-z0-9-\.]*)\.)?     
([a-z0-9-]+)\.       
([a-z]{2,5}) 
(:[0-9]{1,5})? 
(\/)?$/ix 
+0

Gracias?. Eso corrigió el error, pero ahora una entrada como "abcd" es válida. Alguna idea sobre como arreglar eso? –

+1

La actualización debería funcionar. Una cosa más que eliminé fue la [-.] Y la reemplacé por \. – cordsen

+0

¡Gracias, agradezco tu ayuda! :) –

14

No es necesario utilizar una expresión regular aquí. Ruby tiene una forma mucho más fiable para hacer eso:

# Use the URI module distributed with Ruby: 

require 'uri' 

unless (url =~ URI::regexp).nil? 
    # Correct URL 
end 

(esta respuesta proviene de this post :)

+2

Esto no funciona para: "http: // nyimes" (IGNORE SPACE) –

9

(me gusta la respuesta Thomas Hupkens', pero para la visualización de otras personas, te recomiendo direccionable)

No se recomienda el uso de expresiones regulares para validar las URL.

Utilice la biblioteca de URI de Ruby o un reemplazo como Addressable, lo que hace que la validación de URL sea trivial. A diferencia de URI, direccionable también puede manejar caracteres internacionales y TLD.

Ejemplo de Uso:

require 'addressable/uri' 

Addressable::URI.parse("кц.рф") # Works 

uri = Addressable::URI.parse("http://example.com/path/to/resource/") 
uri.scheme 
#=> "http" 
uri.host 
#=> "example.com" 
uri.path 
#=> "/path/to/resource/" 

Y se podría construir una validación personalizada como:

class Example 
    include ActiveModel::Validations 

    ## 
    # Validates a URL 
    # 
    # If the URI library can parse the value, and the scheme is valid 
    # then we assume the url is valid 
    # 
    class UrlValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
     begin 
     uri = Addressable::URI.parse(value) 

     if !["http","https","ftp"].include?(uri.scheme) 
      raise Addressable::URI::InvalidURIError 
     end 
     rescue Addressable::URI::InvalidURIError 
     record.errors[attribute] << "Invalid URL" 
     end 
    end 
    end 

    validates :field, :url => true 
end 

Code Source

+1

después de mirar direccionable, creo que gana sin problemas, gracias – stephenmurdoch

+0

+1 por direccionable PERO no suponga que se planteará ninguna excepción porque no lo hará Dirigible :: URI.parse fallará silenciosamente haciendo su mejor esfuerzo para descubrir el URI. Por ejemplo, supongamos que desea validar un URI incorrecto, como: http: // http: //thing.com. Direccionable llamará al esquema http y al dominio http también, ya que ve el colon como un delimitador de puerto. No se generará ningún error – onetwopunch

1

Prueba esto. Me funciona.
/(ftp | http | https): // (\ w +: {0,1} \ w * @)? (\ S +) (: [0-9] +)? (/ |/([\ W ! #:.?! + = &% @ - /]))/

0

Esto incluirá una manipulación, así como abc.com.it acogida internacional donde la parte .it es opcional

match '/:site', to: 'controller#action' , constraints: { site: /[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}(.[a-zA-Z]{2,63})?/}, via: :get, :format => false