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.