Puis-je améliorer cette vérification regex pour les noms de domaine valides?

StackOverflow https://stackoverflow.com/questions/399932

  •  29-08-2019
  •  | 
  •  

Question

Alors, je travaille sur ce nom de domaine expression régulière. Jusqu'à présent, il semble prendre des noms de domaine avec DLV et TLDs (avec l'option) ccTLD, mais il y a duplication de la liste des TLD. Cela peut-il être refactorisé plus loin?

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]))?$/)
Était-ce utile?

La solution

S'il vous plaît, s'il vous plaît, s'il vous plaît ne pas utiliser une expression régulière fixe et horriblement compliqué comme celui-ci pour correspondre à des noms de domaine connus.

La liste des TLDs est pas statique, en particulier avec l'ICANN regardant un processus simplifié pour les nouveaux gTLD. Même la liste des ccTLDs change parfois!

Jetez un oeil à la liste disponible à partir de http://publicsuffix.org/ et écrire un code qui est capable de télécharger et analyser cette liste à la place.

Autres conseils

Télécharger: http://data.iana.org/ TLD / tlds-alpha par domain.txt

Exemple d'utilisation (dans le 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')

Vous pouvez facteur de la consolidation de la liste domaine de la fonction de validation pour améliorer les performances.

Je ne sais pas assez sur les noms de domaine probablement. Mais pourquoi est-domaines comme « foo.info.com » appareillés? Il semble que le nom de domaine est « info.com » dans ce cas particulier.

Et vous pouvez vous assurer que le nom commence par [a-z \ d]. Je ne pense pas que vous pouvez enregistrer un domaine qui commence par un tiret?

Eh bien comme vous l'avez écrit il, la partie de TLD est équivalent mais plus long que (\.<tldpart>){1,2} mais je suis sûr qu'il pourrait être fixé pour la duplication ...

edit: yech, non, il serait possible, mais essentiellement une liste de force brute très lent pour gérer les duplications, je pense. Simple et plus rapide à mettre les paires TLD possible et DLV + pays dans un grand hashmap et vérifiez la sous-chaîne contre cela.

Je recommande à commencer par les règles établies dans RFC 1035 , et puis remonter la piste - mais seulement si vous avez vraiment vraiment vraiment besoin de le faire à partir de zéro. Un modèle de regex de domaine doit d'être (défendables au deuxième rang aux modèles regex d'adresse e-mail) la chose la plus commune là-bas. Je consultez le site regexlib.com et naviguer à travers ce que d'autres personnes ont fait.

Vous pouvez construire la regex comme une chaîne, puis faire Regexp.new (string).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top