Che cosa è un’espressione regolare che corrisponderà a un nome di dominio valido senza un sottodominio?

Innanzitutto mi dispiace per la 10.000 domanda RegEx,

Mi rendo conto che ci sono altre domande relative al dominio, ma la regex non funziona correttamente, è troppo complessa, o per URL con sottodomini, protocolli e percorsi di file.

Il mio è più semplice, ho bisogno di convalidare un nome di dominio:

google.com

stackoverflow.com

Quindi un dominio nella sua forma più grezza – nemmeno un sottodominio come www.

  1. I caratteri dovrebbero essere solo az | AZ | 0-9 e punto (.) E trattino (-)
  2. La parte del nome di dominio non dovrebbe iniziare o finire con trattino (-) (es. -Google-.com)
  3. La parte del nome dominio deve essere lunga da 1 a 63 caratteri
  4. L’estensione (TLD) può essere qualsiasi cosa sotto le regole n. 1 per ora, potrei convalidarle contro una lista più tardi, dovrebbe essere almeno uno o più caratteri

Modifica: TLD è apparentemente 2-6 caratteri così com’è

no. 4 rivisto: TLD dovrebbe essere etichettato come “sottodominio” in quanto dovrebbe includere cose come .co.uk – Immagino che l’unica validazione ansible (a parte il controllo di una lista) sia “dopo il primo punto ci dovrebbe essere uno o più personaggi secondo le regole # 1

Grazie mille, credimi, ci ho provato!

Beh, è piuttosto semplice un po ‘più snello di quanto sembri (vedi commenti), date le tue esigenze specifiche:

/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/ 

Nota che questo rifiuterà molti domini validi.

So che questo è un po ‘un vecchio post, ma tutte le espressioni regolari qui mancano di un componente molto importante: il supporto per i nomi di dominio IDN.

I nomi di dominio IDN iniziano con xn--. Abilitano caratteri UTF-8 estesi nei nomi di dominio. Ad esempio, lo sapevi che “♡ .com” è un nome di dominio valido? Sì, “love heart dot com”! Per convalidare il nome del dominio, è necessario consentire a http://xn--c6h.com/ di superare la convalida.

Nota: per usare questa espressione regolare, dovrai convertire il dominio in minuscolo e utilizzare anche una libreria IDN per assicurarti di codificare i nomi di dominio in ACE (noto anche come “Codifica compatibile ASCII”). Una buona libreria è GNU-Libidn.

idn (1) è l’interfaccia della riga di comando per la libreria dei nomi di dominio internazionalizzata. L’esempio seguente converte il nome host in UTF-8 nella codifica ACE. L’URL risultante https: //nic.xn--flw351e/ può quindi essere utilizzato come equivalente codificato in ACE di https: // nic. 谷 歌 / .

  $ idn --quiet -a nic.谷歌nic.xn--flw351e 

Questa magica espressione regolare dovrebbe coprire la maggior parte dei domini (anche se, sono sicuro che ci sono molti casi limite validi che ho perso):

 ^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[az]{2,})$ 

Quando scegli una regex di convalida del dominio, dovresti vedere se il dominio corrisponde a quanto segue:

  1. xn--stackoverflow.com
  2. stackoverflow.xn – com
  3. stackoverflow.co.uk

Se questi tre domini non passano, la tua espressione regolare potrebbe non consentire domini legittimi!

Per ulteriori informazioni, consultare la pagina di supporto dei nomi di dominio internazionalizzati dalla Guida all’ambiente internazionale del linguaggio Oracle .

Sentiti libero di provare la regex qui: http://www.regexr.com/3abjr

ICANN mantiene una lista di tld che sono stati delegati e che possono essere usati per vedere alcuni esempi di domini IDN.


Modificare:

  ^(((?!-))(xn--|_{1,1})?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[az]{2,})$ 

Questa espressione regolare fermerà i domini che hanno “-” alla fine di un nome host contrassegnati come validi. Inoltre, consente sottodomini illimitati.

Il mio RegEx è il prossimo:

^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$

va bene per i.oh1.me e per wow.british-library.uk

UPD

Ecco la regola aggiornata

 ^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$ 

Visualizzazione dell'espressione regolare

https://www.debuggex.com/r/y4Xe_hDVO11bv1DV

ora controlla _ o _ all’inizio o alla fine dell’etichetta del dominio.

Solo una piccola correzione – l’ultima parte dovrebbe essere fino a 6. Quindi,

 ^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[az]{2,6}$ 

Il TLD più lungo è museum (6 caratteri) – http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains

La mia scommessa:

 ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$ 

Ha spiegato:

Il nome di dominio è costruito da segmenti. Ecco un segmento (eccetto la finale):

 [a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])? 

Può contenere da 1 a 63 caratteri, non inizia né termina con ‘-‘.

Adesso aggiungi “.” ad esso e ripetere almeno una volta:

 (?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+ 

Quindi collega il segmento finale, che è lungo 2-63 caratteri:

 [a-z0-9][a-z0-9-]{0,61}[a-z0-9] 

Provalo qui: http://regexr.com/3au3g

Risposta accettata non funziona per me, prova questo:

^ ((-?!) [A-Za-z0-9 -] {1,63} (< -?!.) \) + [A-Za-z] {2,6} $

Visita questo Test Cases Unit per la convalida.

Questa risposta è per i nomi di dominio (inclusi i RR di servizio), non i nomi di host (come un nome host di posta elettronica).

 ^(?=.{1,253}\.?$)(?:(?!-|[^.]+_)[A-Za-z0-9-_]{1,63}(?< !-)(?:\.|$)){2,}$ 

È fondamentalmente la risposta del mkyong e in aggiunta:

  • Lunghezza massima di 255 ottetti compresi prefissi di lunghezza e radice nulla.
  • Consenti il ​​trascinamento '.' per la radice dns esplicita.
  • Consenti l'inserimento di '_' per i RR dei domini di servizio, (bug: non impone 15 caratteri max per _ etichette, né richiede almeno un dominio sopra i RR di servizio)
  • Corrisponde a tutti i TLD possibili.
  • Non cattura le etichette dei sottodomini.

Per parti

Lookahead, limita la lunghezza massima tra ^ $ e 253 caratteri con testo finale opzionale ".

 (?=.{1,253}\.?$) 

Guarda avanti, il prossimo carattere non è un '-' e nessun '_' segue alcun carattere prima del prossimo '.'. Vale a dire, far rispettare il fatto che il primo carattere di un'etichetta non è un '-' e solo il primo carattere potrebbe essere un '_'.

 (?!-|[^.]+_) 

Tra 1 e 63 dei caratteri consentiti per etichetta.

 [A-Za-z0-9-_]{1,63} 

Guardare dietro, il carattere precedente non '-'. Vale a dire, imporre che l'ultimo carattere di un'etichetta non sia un '-'.

 (?< !-) 

Forza un '.' alla fine di ogni etichetta tranne l'ultima, dove è facoltativa.

 (?:\.|$) 

Per lo più combinati dall'alto, ciò richiede almeno due livelli di dominio, che non è del tutto corretto, ma di solito un presupposto ragionevole. Passare da {2,} a + se si desidera consentire i TLD o sottodomini relativi non qualificati tramite (ad esempio, localhost, myrouter, a.)

 (?:(?!-|[^.]+_)[A-Za-z0-9-_]{1,63}(?< !-)(?:\.|$)){2,} 

Test unitari per questa espressione.

Grazie per aver indicato la giusta direzione nelle soluzioni di convalida dei nomi di dominio in altre risposte. I nomi di dominio potrebbero essere convalidati in vari modi.

Se è necessario convalidare il dominio IDN nel suo formato leggibile dall’uomo , sarà utile regex \p{L} . Questo permette di abbinare qualsiasi personaggio in qualsiasi lingua.

Nota che l’ ultima parte potrebbe contenere anche i trattini ! Poichè i nomi chineese codificati con punycode potrebbero avere caratteri unicode in tld.

Sono arrivato alla soluzione che corrisponderà per esempio:

  • google.com
  • masełkowski.pl
  • maselkowski.pl
  • m.maselkowski.pl
  • http://www.masełkowski.pl.com
  • xn--masekowski-d0b.pl
  • 中国 互联 网络 信息 中心. 中国
  • Xn – fiqa61au8b7zsevnm8ak20mc4a87e.xn – fiqs8s

Regex è:

 ^[0-9\p{L}][0-9\p{L}-\.]{1,61}[0-9\p{L}]\.[0-9\p{L}][\p{L}-]*[0-9\p{L}]+$ 

Controllare e sintonizzare qui

NOTA: questa espressione regolare è abbastanza permissiva, poiché i nomi di dominio correnti hanno il set di caratteri consentito.

AGGIORNAMENTO : Ancora più semplificato, poiché a-aA-Z\p{L} è uguale a solo \p{L}

NOTA2: L’unico problema è che masełk..owski.pl domini con doppi punti in esso …, come masełk..owski.pl . Se qualcuno sa come risolvere questo problema, per favore migliora.

 ^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[az]{2,7}$ 

[dominio – lettere minuscole e solo 0-9] [può avere un trattino] + [TLD – solo lettere minuscole, deve essere compreso tra 2 e 7 lettere]
http://rubular.com/ è geniale per testare le espressioni regolari!
Modifica: aggiornato TLD massimo di 7 caratteri per “.rentals” come indicato da Dan Caddigan.

Non c’è ancora abbastanza commento da commentare. In risposta alla soluzione di paka, ho scoperto che dovevo regolare tre elementi:

  • Il trattino e il carattere di sottolineatura sono stati spostati a causa del trattino interpretato come un intervallo (come in “0-9”)
  • Aggiunto un punto per i nomi di dominio con molti sottodomini
  • Estesa la lunghezza potenziale per i TLD a 13

Prima:

 ^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$ 

Dopo:

 ^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][-_\.a-zA-Z0-9]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$ 
 ^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]+(\.[a-zA-Z]+)$ 

Per i nuovi gTLD

 /^((?!-)[\p{L}\p{N}-]+(?< !-)\.)+[\p{L}\p{N}]{2,}$/iu 

Ecco il codice completo con l’esempio:

 < ?php function is_domain($url) { $parse = parse_url($url); if (isset($parse['host'])) { $domain = $parse['host']; } else { $domain = $url; } return preg_match('/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/', $domain); } echo is_domain('example.com'); //true echo is_domain('https://example.com'); //true echo is_domain('https://.example.com'); //false echo is_domain('https://localhost'); //false 
 ^((localhost)|((?!-)[A-Za-z0-9-]{1,63}(?< !-)\.)+[A-Za-z]{2,253})$ 

Grazie @mkyong per la base della mia risposta. L'ho modificato per supportare etichette accettabili più lunghe.

Inoltre, "localhost" è tecnicamente un nome di dominio valido. Modificherò questa risposta per accogliere i nomi di dominio internazionalizzati.

 /^((([a-zA-Z]{1,2})|([0-9]{1,2})|([a-zA-Z0-9]{1,2})|([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]))\.)+[a-zA-Z]{2,6}$/ 
  • ([a-zA-Z]{1,2}) -> per accettare solo due caratteri.

  • ([0-9]{1,2}) -> per accettare solo due numeri

se qualcosa supera oltre due ([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]) questa regex si prenderà cura di questo.

Se vogliamo fare la corrispondenza per almeno una volta + sarà usato.

^ [A-zA-Z0-9] [- a-zA-Z0-9] + [a-zA-Z0-9] [az] {2,3}. ([Az] {2,3}.) ? (. [az] {2,3})? $

Esempi che funzionano:

 stack.com sta-ck.com sta---ck.com 9sta--ck.com sta--ck9.com stack99.com 99stack.com sta99ck.com 

Funzionerà anche per le estensioni

 .com.uk .co.in .uk.edu.in 

Esempi che non funzioneranno:

 -stack.com 

funzionerà anche con l’estensione di dominio più lunga ".versicherung"