¿Puedo mejorar esta verificación de expresiones regulares para buscar nombres de dominio válidos?

Entonces, he estado trabajando en esta expresión regular de nombre de dominio. Hasta ahora, parece recoger nombres de dominio con SLD y TLD (con el ccTLD opcional), pero hay una duplicación de la lista de TLD. ¿Se puede refactorizar más?

params[:domain_name].downcase.strip.match(/^[a-z0-9\-]{2,63} \.((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)| (c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]| (g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)| (j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]| (m[acdghklmnopqrstuvwxyz]|me|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)| (p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]| (t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]) (\.((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)| (c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]| (g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)| (j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]| m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)| (n[acefgilopruz]|name|net)|(om|org)| (p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]| (t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))?$/) 

Por favor, por favor, no utilices una expresión regular fija y terriblemente complicada como esta para que coincida con los nombres de dominio conocidos.

La lista de TLD no es estática, particularmente con ICANN mirando un proceso simplificado para nuevos gTLD. ¡Incluso la lista de ccTLD cambia a veces!

Eche un vistazo a la lista disponible en http://publicsuffix.org/ y escriba algún código que pueda descargar y analizar esa lista.

Descargue esto: http://data.iana.org/TLD/tlds-alpha-by-domain.txt

Ejemplo de uso (en Python):

 import re def validate(domain): valid_domains = [ line.upper().replace('.', '\.').strip() for line in open('domains.txt') if line[0] != '#' ] r = re.compile(r'^[A-Z0-9\-]{2,63}\.(%s)$' % ('|'.join(valid_domains),)) return True if r.match(domain.upper()) else False print validate('stackoverflow.com') print validate('omnom.nom') 

Puede factorizar la creación de listas de dominios fuera de la función de validación para ayudar al rendimiento.

No sé lo suficiente sobre los nombres de dominio, probablemente. ¿Pero por qué los dominios como “foo.info.com” coinciden? Parece que el nombre de dominio es “info.com” en ese caso particular.

Y es posible que desee asegurarse de que el nombre empiece por [az \ d]. No creo que puedas registrar un dominio que comience con un guion.

Bueno, como lo tienen escrito, la parte de TLD es equivalente pero más larga que (\.){1,2} pero estoy seguro de que podría arreglarse para la duplicación …

editar: yech, no, sería posible, pero esencialmente una lista de fuerza bruta muy lenta para manejar las duplicaciones, creo. Más simple y más rápido para poner los posibles pares de países TLD y SLD + en un gran hashmap y comprobar la subcadena contra eso.

Recomiendo comenzar con las reglas establecidas en RFC 1035 , y luego trabajar hacia atrás, pero solo si realmente realmente necesita hacer esto desde cero. Un patrón de expresión regex de dominio tiene que ser (lo que es discutible por segundo solo a los patrones de expresiones regulares de dirección de correo electrónico) lo más común que existe. Revisaría el sitio regexlib.com y vería lo que otras personas han hecho.

Puedes construir la expresión regular como una cadena y luego hacer Regexp.new (cadena).