variable validar validaciones validacion tipo programacion numeros numero especiales espacios entero datos comprobar caracteres blanco python regex validation hostname fqdn

python - validaciones - Validar una cadena de nombre de host



validar numero entero python (8)

Aquí hay una versión un poco más estricta de la respuesta de Tim Pietzcker con las siguientes mejoras:

  • Limite la longitud del nombre de host a 253 caracteres (después de quitar el punto final).
  • Limite el conjunto de caracteres a ASCII (es decir, use [0-9] lugar de /d ).
  • Verifique que el TLD no sea totalmente numérico.

import re def is_valid_hostname(hostname): if hostname[-1] == ".": # strip exactly one dot from the right, if present hostname = hostname[:-1] if len(hostname) > 253: return False labels = hostname.split(".") # the TLD must be not all-numeric if re.match(r"[0-9]+$", labels[-1]): return False allowed = re.compile(r"(?!-)[a-z0-9-]{1,63}(?<!-)$", re.IGNORECASE) return all(allowed.match(label) for label in labels)

¿Siguiendo con la expresión regular para hacer coincidir el nombre de host o la dirección IP? y el uso de Restricciones en nombres de host válidos como referencia, ¿cuál es la forma más legible y concisa para hacer coincidir / validar un nombre de host / fqdn (nombre de dominio totalmente calificado) en Python? He respondido con mi intento a continuación, las mejoras son bienvenidas.


Complementario a la respuesta @TimPietzcker. Underscore es un nombre de host válido, doubel dash es común para IDN punycode. El número de puerto debe ser eliminado. Esta es la limpieza del código.

import re def is_valid_hostname(hostname): if len(hostname) > 255: return False hostname = hostname.rstrip(".") allowed = re.compile("(?!-)[A-Z/d/-/_]{1,63}(?<!-)$", re.IGNORECASE) return all(allowed.match(x) for x in hostname.split(".")) # convert your unicode hostname to punycode (python 3 ) # Remove the port number from hostname normalise_host = hostname.encode("idna").decode().split(":")[0] is_valid_hostanme(normalise_host )


Me gusta la minuciosidad de la respuesta de Tim Pietzcker, pero prefiero descargar parte de la lógica de las expresiones regulares para facilitar la lectura. Honestamente, tuve que buscar el significado de esas partes (? "notación de extensión"). Además, creo que el enfoque "doblemente negativo" es más obvio porque limita la responsabilidad de la expresión regular a simplemente encontrar cualquier carácter no válido. Me gusta que re.IGNORECASE permita acortar la expresión regular.

Así que aquí hay otra oportunidad; es más largo, pero parece algo así como la prosa. Supongo que "legible" está en desacuerdo con "conciso". Creo que todas las restricciones de validación mencionadas en el hilo hasta el momento están cubiertas:

def isValidHostname(hostname): if len(hostname) > 255: return False if hostname.endswith("."): # A single trailing dot is legal hostname = hostname[:-1] # strip exactly one dot from the right, if present disallowed = re.compile("[^A-Z/d-]", re.IGNORECASE) return all( # Split by labels and verify individually (label and len(label) <= 63 # length is within proper range and not label.startswith("-") and not label.endswith("-") # no bordering hyphens and not disallowed.search(label)) # contains only legal characters for label in hostname.split("."))


Procese cada etiqueta DNS individualmente excluyendo los caracteres no válidos y garantizando una longitud distinta de cero.

def isValidHostname(hostname): disallowed = re.compile("[^a-zA-Z/d/-]") return all(map(lambda x: len(x) and not disallowed.search(x), hostname.split(".")))


Según The Old New Thing , la longitud máxima de un nombre DNS es de 253 caracteres. (Se permite uno de hasta 255 octetos, pero 2 de ellos son consumidos por la codificación).

import re def validate_fqdn(dn): if dn.endswith(''.''): dn = dn[:-1] if len(dn) < 1 or len(dn) > 253: return False ldh_re = re.compile(''^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$'', re.IGNORECASE) return all(ldh_re.match(x) for x in dn.split(''.''))

Uno podría abogar por aceptar nombres de dominio vacíos, o no, dependiendo del propósito de uno.


Si está buscando validar el nombre de un host existente, la mejor manera es tratar de resolverlo. Nunca escribirás una expresión regular para proporcionar ese nivel de validación.


def is_valid_host(host): ''''''IDN compatible domain validator'''''' host = host.encode(''idna'').lower() if not hasattr(is_valid_host, ''_re''): import re is_valid_host._re = re.compile(r''^([0-9a-z][-/w]*[0-9a-z]/.)+[a-z0-9/-]{2,15}$'') return bool(is_valid_host._re.match(host))


import re def is_valid_hostname(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("(?!-)[A-Z/d-]{1,63}(?<!-)$", re.IGNORECASE) return all(allowed.match(x) for x in hostname.split("."))

asegura que cada segmento

  • contiene al menos un personaje y un máximo de 63 caracteres
  • consiste solo de caracteres permitidos
  • no comienza ni termina con un guion.

También evita los dobles negativos ( not disallowed ), y si el hostname termina en a . , eso está bien, también. Fallará (y debería) si el hostname termina en más de un punto.