2010-05-24 10 views
9

Ich benutze Python und möchte eine einfache API oder Regex, um die Gültigkeit eines Domainnamens zu überprüfen. Durch die Gültigkeit bin ich syntaktisch gültig und nicht, ob der Domainname tatsächlich im Internet existiert oder nicht.Suchen Sie nach einem gültigen Domänennamen in einer Zeichenfolge?

+0

Aus welchem ​​Grund? Wenn es sich um eine E-Mail handelt, sollte die tatsächliche Gültigkeit überprüft werden, indem eine DNS-Abfrage für den MX-Eintrag durchgeführt wird, nicht durch regexp. – Kimvais

+5

Nein. Es gibt keinen Vorteil beim Suchen nach bekannten ungültigen Namen, es ist nur eine Verschwendung von Zeit und Ressourcen. Außerdem benötigen Sie keinen MX-Record, um E-Mails zuzustellen, ein A-Record ist ausreichend. – Synchro

+0

Scheint es bereits diskutiert [HIER] (http://stackoverflow.com/questions/1128168/validation-for-url-domain-using-regex-rails). – Incognito

Antwort

13

Jeder Domänenname ist (syntaktisch) gültig, wenn es sich um eine durch Punkte getrennte Liste von Bezeichnern handelt, die nicht länger als 63 Zeichen sind und aus Buchstaben, Ziffern und Bindestrichen (keine Unterstriche) bestehen.

So:

r'[a-zA-Z\d-]{,63}(\.[a-zA-Z\d-]{,63})*' 

wäre ein Anfang. Natürlich können heutzutage einige nicht-ASCII-Zeichen erlaubt sein (eine sehr neue Entwicklung), die die Parameter sehr verändern - müssen Sie damit umgehen?

+0

kann eine Kennung mit einem Bindestrich beginnen/enden? – Amarghosh

+0

Danke! Nein, ich brauche keine grundlegende Überprüfung, um sicherzustellen, dass keine schwarzen Listen wie "! "usw. – demos

+0

Alex, ich weiß, dass du ein appengine Guru bist, bitte hilf mir dabei: http: // stackoverflow.com/questions/2894808/Erstellen-Auto-Inkrementieren-Spalte-in-Google-Appengine Vielen Dank im Voraus! – demos

5
r'^(?=.{4,255}$)([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]\.)+[a-zA-Z0-9]{2,5}$' 
  • Lookahead stellt sicher, dass es ein Minimum von 4 (a.in) und maximal 255 Zeichen
  • einer oder mehr Markierungen (die durch Punkte getrennt) hat mit einer Länge zwischen 1 bis 63, und endend mit alphanumerischen Zeichen und mit alphanumerischen Zeichen und Bindestrichen in der Mitte.
  • durch einen Top-Level-Domain-Namen Gefolgt (deren maximale Länge beträgt 5 für Museum)
+1

Dies kann keinen Punycode speichern Die kürzeste kyrillisch geschriebene Zwei-Buchstaben-Top-Level-Domain besteht aus 6 Buchstaben in Punycode. – kaleissin

+2

Museum ist 6 Zeichen, nicht 5. –

+0

Es ist eine schlechte Idee, die erwartete TLD-Länge hart-Code, vor allem jetzt, dass IDN TLDs kommen, die codiert sind und somit viel länger als 5 kommen. –

1

Beachten Sie, dass, während Sie etwas mit regulären Ausdrücken tun, der zuverlässigste Weg für gültigen Domain-Namen zu testen ist zu versuchen, tatsächlich den Namen (mit socket.getaddrinfo) zu lösen:

from socket import getaddrinfo 

result = getaddrinfo("www.google.com", None) 
print result[0][4] 

Beachten Sie, dass dies technisch Sie offen für DoS verlassen kann (wenn jemand tausende von ungültigen Domain-Namen trägt, kann es eine Weile dauern, ungültig nam zu lösen es) aber Sie könnten einfach jemanden einschränken, der das versucht.

Der Vorteil davon ist, dass es "hotmail.con" als ungültig (anstelle von "hotmail.com" sagen wird), während eine Regex sagen würde "hotmail.con" ist gültig.

+2

Dies ist wirklich ein separates Problem und keine gute Antwort auf die Frage. Angesichts der Tatsache, dass DNS für Exploits in der Vergangenheit verwendet wurde, ist es nur sinnvoll, zu überprüfen, ob eine Zeichenfolge mindestens gültig gültig ist, bevor sie verwendet wird. Außerdem ist sie um Größenordnungen schneller als eine DNS-Suche. Das ähnelt dem Ausführen von Code, um zu sehen, ob es bösartig ist! – Synchro

+0

Dies kann nicht für die Validierung von Domänennamen verwendet werden, die erstellt werden sollen, nur für bereits existierende Domänennamen. – nerdoc

+0

Warum gibt eine gültige URL wie https: // google.com/'einen Fehler zurück? –

0

Ich habe das schon mit:

(r'(\.|\/)(([A-Za-z\d]+|[A-Za-z\d][-])+[A-Za-z\d]+){1,63}\.([A-Za-z]{2,3}\.[A-Za-z]{2}|[A-Za-z]{2,6})') 

, um sicherzustellen, folgt sie entweder nach Punkt (www.) Oder/(http: //) und der Bindestrich nur innerhalb der Name kommt und solche Suffixe übereinstimmen wie gov.uk auch.

0

Die Antworten sind alle ziemlich veraltet mit der Spezifikation an dieser Stelle. Ich glaube, das folgende wird die aktuelle Spezifikation korrekt entsprechen:

r'^(?=.{1,253}$)(?!.*\.\..*)(?!\..*)([a-zA-Z0-9-]{,63}\.){,127}[a-zA-Z0-9-]{1,63}$' 
Verwandte Themen