如何解析版本号字符串并匹配规则返回对应关联值
版本号匹配规则实现方案
核心实现思路
- 第一步:实现通用版本号比较函数,支持对比两个不含通配符的版本号的大小,返回大于/等于/小于三种状态
- 第二步:预处理动态规则集合
- 把所有规则键拆分为分段数组,带
*通配符的单独标记通配符所在的位置 - 把所有规则按版本号从高到低排序,通配符版本的排序按通配符替换为0来计算基准版本,比如
1.0.*的基准版本为1.0.0
- 把所有规则键拆分为分段数组,带
- 第三步:按优先级匹配输入版本
- 首先判断输入版本是否高于规则集合里最高的版本,符合则直接返回
null - 按从高到低的顺序遍历预处理后的规则:
- 若规则不带通配符:直接对比输入版本和规则版本,若输入版本 >= 规则版本,直接返回当前规则对应的值
- 若规则带通配符:先匹配通配符位置之前的分段是否完全一致,若一致直接返回当前规则对应的值;若不一致再判断输入版本是否 >= 规则的基准版本,符合则返回对应值
- 首先判断输入版本是否高于规则集合里最高的版本,符合则直接返回
代码示例(JavaScript实现)
// 版本号比较函数:v1 > v2返回1,相等返回0,v1 < v2返回-1 function compareVersion(v1, v2) { const arr1 = v1.split('.').map(Number); const arr2 = v2.split('.').map(Number); const maxLen = Math.max(arr1.length, arr2.length); for (let i = 0; i < maxLen; i++) { const num1 = arr1[i] || 0; const num2 = arr2[i] || 0; if (num1 > num2) return 1; if (num1 < num2) return -1; } return 0; } // 预处理规则 function preprocessRules(rules) { return Object.entries(rules) .map(([ruleKey, value]) => { const segments = ruleKey.split('.'); const wildcardIndex = segments.indexOf('*'); // 生成基准版本用于排序 const baseVersion = wildcardIndex === -1 ? ruleKey : segments.map((seg, idx) => idx >= wildcardIndex ? 0 : seg).join('.'); return { ruleKey, value, wildcardIndex, baseVersion, segments: wildcardIndex === -1 ? segments : segments.slice(0, wildcardIndex) }; }) // 按基准版本从高到低排序 .sort((a, b) => compareVersion(b.baseVersion, a.baseVersion)); } // 匹配版本号 function matchVersion(inputVersion, processedRules) { // 先判断是否大于最高规则版本 if (compareVersion(inputVersion, processedRules[0].baseVersion) > 0) { return null; } // 遍历规则匹配 for (const rule of processedRules) { if (rule.wildcardIndex === -1) { // 无通配符规则,大于等于就匹配 if (compareVersion(inputVersion, rule.ruleKey) >= 0) { return rule.value; } } else { // 有通配符规则,先匹配前缀 const inputSegs = inputVersion.split('.').slice(0, rule.segments.length); if (inputSegs.join('.') === rule.segments.join('.')) { return rule.value; } // 前缀不匹配的话判断是否大于等于基准版本 if (compareVersion(inputVersion, rule.baseVersion) >= 0) { return rule.value; } } } // 所有规则都不匹配(比如版本低于所有规则基准版本)返回最低规则对应的值 return processedRules.at(-1).value; } // 测试示例 const rules = { "3.2.1": "testing_server", "2.8.10": "second_value", "1.0.*": "last value" }; const processedRules = preprocessRules(rules); console.log(matchVersion("1.2.3", processedRules)); // 输出last value console.log(matchVersion("2.8.10", processedRules)); // 输出second_value console.log(matchVersion("3.0.0", processedRules)); // 输出testing_server console.log(matchVersion("3.3.0", processedRules)); // 输出null console.log(matchVersion("0.9.1", processedRules)); // 输出last value
方案验证说明
示例输入1.2.3经过匹配,会命中1.0.*对应的last value,完全符合需求。如果后续需要新增规则,只需要在规则对象中添加对应条目,重新执行预处理逻辑即可生效,无需修改匹配逻辑。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

