域名格式校验正则的编写
域名由若干标签用点连接而成,每个标签有自己的长度与字符约束。写校验规则前要先把三类输入分开:普通域名、以点结尾的完整限定名、以及带区域后缀的内部名称(例如 DNS 记录里的下划线前缀)。混在一起写会让规则既过严又过宽。
基本信息
| 总长度 | 不超过 253 字符(不含末尾的点),末尾点表示完整限定名 |
|---|---|
| 标签规则 | 每个标签 1 到 63 字符,由字母、数字与连字符组成,不以连字符开头或结尾 |
| 大小写 | 域名不区分大小写,校验前建议统一转小写 |
| 国际化 | 非 ASCII 域名在实际传输中使用 punycode 形式(以 xn-- 开头) |
| 特例 | DNS 记录名可含下划线(如服务发现前缀),但普通主机名与网站域名不含 |
典型使用场景
- 站点绑定校验:添加域名时先挡掉形状错误的输入,避免写入无效配置
- 白名单匹配:把允许的域名规范成小写后比较,避免大小写差异绕过
- 证书域名检查:校验待签发清单里的域名格式,减少签发失败
- 日志与报告中提取域名:先从文本里抽取候选,再逐个按规则校验
- 爬虫与链接清洗:区分外链域名与站内链接,格式校验是第一步
校验写法示例
校验写法示例
# 基础校验:总长前瞻、标签规则、至少两个标签、顶级标签至少两个字母
^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,}$
# 允许单标签主机名的内网场景:去掉后半段的强制点号
^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$
# 允许下划线的 DNS 记录名:把下划线加进首个字符集
^[A-Za-z0-9_](?:[A-Za-z0-9_-]{0,61}[A-Za-z0-9_])?$
name = name.rstrip('.') # 处理末尾点,先归一化再校验
name = name.lower() # 统一小写,避免大小写绕过白名单约束与校验方式
| 约束 | 数值 | 校验方式 |
|---|---|---|
| 总长度 | 不超过 253 | 整串前瞻或代码统计长度 |
| 标签长度 | 1 到 63 | 量词表达,注意首尾字符单独限制 |
| 标签首尾 | 不能是连字符 | 首字符与末字符的字符集分开写 |
| 标签数量 | 至少两个(内网主机名除外) | 用带点号的重复结构表达 |
| 字符集 | 字母、数字、连字符 | 按用途决定是否允许下划线 |
把长度约束写成整串前瞻比事后统计更集中,但注意前瞻里的点号表示任意字符不匹配换行,多行输入时要显式排除换行或先按行切分,否则超长多行文本可能被判为长度合规。
纯数字顶级标签、超长标签组合等边界是否被接受,与具体注册规则和解析实现有关;面向公众的入口建议以注册局与解析器实际行为为准,不要仅凭正则放行。