Espressione regolare per abbinare nome host o indirizzo IP DNS?

Qualcuno ha un’espressione regolare a portata di mano che corrisponderà a qualsiasi nome host o indirizzo IP legale?

È facile scrivere uno che funzioni il 95% delle volte, ma spero di ottenere qualcosa che sia ben testato per corrispondere esattamente alle specifiche RFC più recenti per i nomi di host DNS.

È ansible utilizzare le seguenti espressioni regolari separatamente o combinandole in un’espressione OR congiunta.

ValidIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"; ValidHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"; 

ValidIpAddressRegex corrisponde agli indirizzi IP validi e ai nomi host validi ValidHostnameRegex . A seconda della lingua che usi \ potrebbe essere necessario sfuggire con \.


ValidHostnameRegex è valido come da RFC 1123 . Originariamente, RFC 952 specificava che i segmenti hostname non potevano iniziare con una cifra.

http://en.wikipedia.org/wiki/Hostname

Le specifiche originali dei nomi host in RFC 952 , impongono che le etichette non possano iniziare con una cifra o con un trattino e non devono terminare con un trattino. Tuttavia, una specifica successiva ( RFC 1123 ) consentiva alle etichette del nome host di iniziare con le cifre.

 Valid952HostnameRegex = "^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$"; 

Il nome host regex di Smink non osserva la limitazione della lunghezza delle singole etichette all’interno di un nome host. Ogni etichetta all’interno di un nome host valido non può contenere più di 63 ottetti.

  ValidHostnameRegex = "^ ([a-zA-Z0-9] | [a-zA-Z0-9] [a-zA-Z0-9 \ -] {0,61} [a-zA-Z0-9]) \
 (\ ([A-zA-Z0-9] |. [A-zA-Z0-9] [a-zA-Z0-9 \ -] {0,61} [a-zA-Z0-9])) * $" 

Si noti che il backslash alla fine della prima riga (sopra) è la syntax della shell Unix per dividere la linea lunga. Non fa parte dell’espressione regolare stessa.

Ecco solo la normale espressione su una singola riga:

  ^ ([A-zA-Z0-9] | [a-zA-Z0-9] [a-zA-Z0-9 \ -] {0,61} [a-zA-Z0-9]) (\. ([a-zA-Z0-9] | [a-zA-Z0-9] [a-zA-Z0-9 \ -] {0,61} [a-zA-Z0-9])) * $ 

È inoltre necessario verificare separatamente che la lunghezza totale del nome host non superi i 255 caratteri . Per ulteriori informazioni, consultare RFC-952 e RFC-1123.

Per abbinare un indirizzo IP valido usa la seguente espressione regolare:

 (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3} 

invece di:

 ([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])){3} 

Spiegazione

Molti motori regex corrispondono alla prima possibilità nella sequenza OR . Ad esempio, prova la seguente espressione regolare:

 10.48.0.200 

Test

Prova la differenza tra buono e cattivo

Non riesco a modificare il post principale, quindi aggiungerò qui la mia risposta.

Per hostname – risposta facile, su esempio egrep qui – http: //www.linuxinsight.com/how_to_grep_for_ip_addresses_using_the_gnu_egrep_utility.html

 egrep '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}' 

Anche se il caso non tiene conto di valori come 0 nell’ottetto del pugno, e valori maggiori di 254 (ip addr) o 255 (netmask). Forse un’ulteriore dichiarazione if sarebbe d’aiuto.

Per quanto riguarda il nome dns legale dns, purché si stia controllando solo i nomi di host in internet (e non in intranet), ho scritto il seguente frammento, un mix di shell / php ma dovrebbe essere applicabile come qualsiasi espressione regolare.

prima vai sul sito Web di ietf, scarica e analizza un elenco di nomi di dominio di livello 1 legale:

 tld=$(curl -s http://data.iana.org/TLD/tlds-alpha-by-domain.txt | sed 1d | cut -f1 -d'-' | tr '\n' '|' | sed 's/\(.*\)./\1/') echo "($tld)" 

Questo dovrebbe darti un bel pezzo di codice che controlla la legalità del top name, come .com .org o .ca

Quindi aggiungi la prima parte dell’espressione in base alle linee guida trovate qui – http: //www.domainit.com/support/faq.mhtml?category=Domain_FAQ&question=9 (qualsiasi combinazione alfanumerica e simbolo “-“, dash non dovrebbe essere in l’inizio o la fine di un ottetto.

 (([a-z0-9]+|([a-z0-9]+[-]+[a-z0-9]+))[.])+ 

Quindi metti tutto insieme (esempio preg_match in PHP):

 $pattern = '/^(([a-z0-9]+|([a-z0-9]+[-]+[a-z0-9]+))[.])+(AC|AD|AE|AERO|AF|AG|AI|AL|AM|AN|AO|AQ|AR|ARPA|AS|ASIA|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BIZ|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CAT|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|COM|COOP|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|INFO|INT|IO|IQ|IR|IS|IT|JE|JM|JO|JOBS|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MUSEUM|MV|MW|MX|MY|MZ|NA|NAME|NC|NE|NET|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|ORG|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PRO|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TEL|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TRAVEL|TT|TV|TW|TZ|UA|UG|UK|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XN|XN|XN|XN|XN|XN|XN|XN|XN|XN|XN|YE|YT|YU|ZA|ZM|ZW)[.]?$/i'; if (preg_match, $pattern, $matching_string){ ... do stuff } 

Potresti anche voler aggiungere un’istruzione if per verificare che la stringa che controlli sia più corta di 256 caratteri – http://www.ops.ietf.org/lists/namedroppers/namedroppers.2003/msg00964.html

 def isValidHostname(hostname): if len(hostname) > 255: return False if hostname[-1:] == ".": hostname = hostname[:-1] # strip exactly one dot from the right, # if present allowed = re.compile("(?!-)[AZ\d-]{1,63}(? 

Penso che questo sia il miglior regex di convalida IP. per favore controlla una volta !!!

 ^(([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))\.){3}([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))$ 
 /^(?:[a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]+[a-zA-Z0-9])(?:\.[a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]+[a-zA-Z0-9])?$/ 

localhost же есть

 "^((\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\.){3}(\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])$" 

Funziona con indirizzi IP validi:

 regex = '^([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])[.]([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])[.]([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])[.]([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])$' 

Vale la pena notare che ci sono librerie per la maggior parte delle lingue che fanno questo per te, spesso incorporate nella libreria standard. È probabile che tali librerie vengano aggiornate molto più spesso rispetto al codice che hai copiato da una risposta Stack Overflow quattro anni fa e dimenticato. E naturalmente, in genere, analizzeranno anche l’indirizzo in una forma utilizzabile, piuttosto che limitarsi a dare una corrispondenza con un gruppo di gruppi.

Ad esempio, rilevando e analizzando IPv4 in (POSIX) C:

 #include  #include  int main(int argc, char *argv[]) { for (int i=1; i!=argc; ++i) { struct in_addr addr = {0}; printf("%s: ", argv[i]); if (inet_pton(AF_INET, argv[i], &addr) != 1) printf("invalid\n"); else printf("%u\n", addr.s_addr); } return 0; } 

Ovviamente, tali funzioni non funzioneranno se stai cercando, ad esempio, di trovare tutti gli indirizzi validi in un messaggio di chat, ma anche lì, potrebbe essere più facile usare una regex semplice ma troppo zelante per trovare potenziali corrispondenze, e quindi usare il libreria per analizzarli.

Ad esempio, in Python:

 >>> import ipaddress >>> import re >>> msg = "My address is 192.168.0.42; 192.168.0.420 is not an address" >>> for maybeip in re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', msg): ... try: ... print(ipaddress.ip_address(maybeip)) ... except ValueError: ... pass 

Ecco una regex che ho usato in Ant per ottenere un IP host host o un nome host da ANT_OPTS. Questo è stato usato per ottenere l’IP del proxy in modo da poter eseguire un test Ant “isreachable” prima di configurare un proxy per una JVM biforcuta.

 ^.*-Dhttp\.proxyHost=(\w{1,}\.\w{1,}\.\w{1,}\.*\w{0,})\s.*$ 

Ho trovato che funziona abbastanza bene per gli indirizzi IP. Convalida come la risposta superiore ma garantisce anche che l’ip sia isolato, quindi nessun testo o più numeri / decimali sono successivi o precedenti all’ip.

?? (?! <\ S) (: (: \ d | [1-9] \ D | 1 \ d \ d | 2 [0-4] \ d | 25 [0-5]) \ b |. \ b) {7} (?! \ S)

 AddressRegex = "^(ftp|http|https):\/\/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5})$"; HostnameRegex = /^(ftp|http|https):\/\/([a-z0-9]+\.)?[a-z0-9][a-z0-9-]*((\.[az]{2,6})|(\.[az]{2,6})(\.[az]{2,6}))$/i 

questo viene usato solo per questo tipo di convalida

funziona solo se http://www.kk.com http://www.kk.co.in

non funziona per

http://www.kk.com/ http: //www.kk.co.in.kk

http://www.kk.com/dfas http://www.kk.co.in/

 public string GetPublicIP() { var direction = string.Empty; var request = WebRequest.Create("http://checkip.dyndns.org/"); using (var response = request.GetResponse()) using (var stream = new StreamReader(response.GetResponseStream())) { direction = stream.ReadToEnd(); } var matches = matchIp.Match(direction); return matches.Captures.Count != 0 ? matches.Captures[0].Value : string.Empty; } 

prova questo:

 ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) 

funziona nel mio caso.

Per quanto riguarda gli indirizzi IP, sembra che ci sia qualche discussione sull’opportunità di includere gli zeri iniziali. Era una volta la pratica comune ed è generalmente accettato, quindi direi che dovrebbero essere contrassegnati come validi indipendentemente dalle preferenze attuali. C’è anche qualche ambiguità sul fatto che il testo prima e dopo la stringa debba essere validato e, ancora una volta, penso che dovrebbe. 1.2.3.4 è un IP valido ma 1.2.3.4.5 non lo è e né la parte 1.2.3.4 né la parte 2.3.4.5 dovrebbero risultare in una corrispondenza. Alcune delle preoccupazioni possono essere gestite con questa espressione:

 grep -E '(^|[^[:alnum:]+)(([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])([^[:alnum:]]|$)' 

La parte sfortunata qui è il fatto che la parte regex che convalida un ottetto viene ripetuta come è vero in molte soluzioni offerte. Sebbene sia meglio che per le istanze del pattern, la ripetizione può essere completamente eliminata se le subroutine sono supportate nella regex utilizzata. Il prossimo esempio abilita quelle funzioni con lo switch -P di grep e sfrutta anche la funzionalità lookahead e lookbehind. (Il nome della funzione che ho selezionato è “o” per l’ottetto. Avrei potuto usare “ottetto” come nome ma volevo essere conciso).

 grep -P '(?([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(\.\g){3}(?![\d\w\.])' 

La gestione del punto potrebbe effettivamente creare dei falsi negativi se gli indirizzi IP sono in un file con testo sotto forma di frasi poiché il periodo potrebbe seguire senza che questo faccia parte della notazione puntata. Una variante di quanto sopra potrebbe risolvere il problema:

 grep -P '(?([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(\.\g){3}(?!([\d\w]|\.\d))' 
 >>> my_hostname = "testhostn.ame" >>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname)) True >>> my_hostname = "testhostn....ame" >>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname)) False >>> my_hostname = "testhostn.A.ame" >>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname)) True 

cosa ne pensi di questo?

 ([0-9]{1,3}\.){3}[0-9]{1,3} 

su php: filter_var(gethostbyname($dns), FILTER_VALIDATE_IP) == true ? 'ip' : 'not ip' filter_var(gethostbyname($dns), FILTER_VALIDATE_IP) == true ? 'ip' : 'not ip'

Verifica dei nomi host come … mywebsite.co.in, thangaraj.name, 18thangaraj.in, thangaraj106.in ecc.,

 [az\d+].*?\\.\w{2,4}$ 

Ho pensato a questo semplice modello di corrispondenza regolare per la corrispondenza dell’indirizzo IP \ d + [.] \ D + [.] \ D + [.] \ D +