ホスト名またはIPアドレスに一致する正規表現 をたどって、参照として 有効なホスト名の制限 を使用して、 Pythonのホスト名/ fqdn(完全修飾ドメイン名)?私は以下の私の試みで答えました、改善は歓迎します。
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("."))
各セグメントが
また、二重否定(not disallowed
)も回避され、hostname
が.
で終わる場合も問題ありません。 hostname
が複数のドットで終わっている場合は失敗します(そして失敗するはずです)。
The Old New Thing によると、DNS名の最大長は253文字です。 (1つは最大255オクテットまで許可されていますが、そのうちの2つはエンコードによって消費されます。)
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('.'))
目的に応じて、空のドメイン名を受け入れるかどうかを主張できます。
Tim Pietzckerの回答 の少し厳密なバージョンを以下に示します。
[0-9]
の代わりに \d
)。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)
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))
私はTim Pietzckerの答えの完全性が好きですが、読みやすくするために、正規表現からロジックの一部をオフロードすることを好みます。正直なところ、私はそれらの意味を調べなければなりませんでした(?
「拡張子表記」パーツ。さらに、「ダブルネガティブ」アプローチは、正規表現の責任が無効な文字を見つけることだけに制限されるという点で、より明白だと思います。 re.IGNORECASEを使用すると、正規表現を短くできるので気に入っています。
これが別のショットです。長いですが、散文のようなものです。 「可読」は「簡潔」とは少し矛盾していると思います。これまでにスレッドで述べた検証の制約はすべてカバーされていると思います。
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("."))
私はこの正規表現がPythonで役立つと思います: '^([a-zA-Z0-9] +(\。| \-))* [a-zA-Z0-9] + $'
車輪を再発明しないでください。ライブラリを使用できます。バリデータ。または、コピーできます そのコード :
pip install validators
import validators
if validators.domain('example.com')
print('this domain is valid')
この純粋な正規表現は、すべてのパラメーターを満たす必要があります:^(?=.{1,253}\.?$)(?!-)[A-Za-z0-9\-]{1,63}(\.[A-Za-z0-9\-]{1,63})*\.?(?<!-)$
@TimPietzckerの回答を無料で。 アンダースコア は有効なホスト名文字です(ただしドメイン名には使用できません)。 IDN punycodeドメイン(xn--など)の場合、ダブルダッシュが一般的です。ポート番号を取り除く必要があります。これはコードのクリーンアップです。
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 )