语义化版本号校验写法
语义化版本把版本写成主版本、次版本、修订号三段数字,后面可跟预发布标识与构建元数据。规则里有两个容易忽略的点:数字标识不允许前导零,构建元数据不参与版本先后比较。校验该格式时最稳的做法是采用规范给出的正则,而不是自己临时拼一条。
基本信息
| 三段数字 | 主版本、次版本、修订号,取值 0 或非零开头的非负整数 |
|---|---|
| 预发布标识 | 用连字符接在后,点分隔的多段;数字段同样不允许前导零 |
| 构建元数据 | 用加号接在后,点分隔的多段;允许前导零,不参与优先级比较 |
| 排序规则 | 先比三段数字;有预发布标识的版本低于对应正式版;构建元数据被忽略 |
典型使用场景
- 发布流水线校验:打包前确认版本号格式合规,避免错误版本进入制品库
- 依赖范围解析:判断约束表达式是否合法,再交给版本库比较大小
- 标签命名规范:把版本与标签前缀分离后再校验,不要在校验里混入前缀
- 制品库巡检:批量检查历史标签是否存在前导零等不规范写法
- 升级判定:比较新旧版本时用专门库,而不是字符串或正则
校验写法与比较
校验写法与比较
# 规范化写法:三段数字、可选预发布、可选构建元数据
^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$
# 只校验三段数字的宽松写法,不含预发布与构建元数据
^\d+\.\d+\.\d+$
# 比较大小不要用字符串或正则,交给专门库
semver.compare('1.10.0', '1.9.0') # 返回 1,表示前者更大
# 带前缀的标签要先剥离前缀再校验
version = tag.lstrip('v') # 处理形如 v1.2.3 的标签各段规则
| 组成 | 允许形式 | 常见错误 |
|---|---|---|
| 主次修订号 | 0 或非零开头的整数 | 写成 01 这类前导零 |
| 预发布标识 | 点分隔的数字或字母数字连字符段 | 数字段带前导零 |
| 构建元数据 | 点分隔的字母数字连字符段 | 当作比较依据 |
| 前缀 | 规范不含前缀 | 把版本前缀写进校验规则 |
预发布版本的排序规则是逐段比较,数字段按数值比、非数字段按字典序比,段数少的排在前面;具体细节以语义化版本官方规范为准,实际项目里直接使用成熟的版本库比自行实现更稳。
很多生态会在版本号前加前缀(例如字母 v),这属于各生态的约定而不在规范内;校验时先剥离前缀,再按规范校验主体,可以让规则同时适用于多种标签风格。