• 版本号正则校验及大小比较


    版本号

    1. 定义

    版本号定义可以参考语义化版本 2.0.0,本文只考虑三位版本号,不考虑先行版本号和版本编译信息。具体如下:

    版本格式:主版本号.次版本号.修订号,版本号递增规则如下:

    1. 主版本号:当你做了不兼容的 API 修改,
    2. 次版本号:当你做了向下兼容的功能性新增,
    3. 修订号:当你做了向下兼容的问题修正。

    2. 格式

    采用 主版本号.次版本号.修订号的格式,且只能使用数字,不能以0开头。

    正则表达式为:

    ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$
    
    • 1

    对应java程序及单元测试

        private static final String PATTERN_STR = "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$";
    
        private static final Pattern VERSION_PATTERN = Pattern.compile(PATTERN_STR);
    
        /**
         * 是否是有效的版本号
         *
         * @param input 字符串
         * @return 是否是有效的版本号
         */
        public static boolean isValidVersion(String input) {
            if (input == null) {
                return false;
            }
            return VERSION_PATTERN.matcher(input).matches();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    对应单元测试代码:

        private static Stream<String> validVersionProvider() {
            return Stream.of(
                    "0.0.4",
                    "1.2.3",
                    "10.20.30",
                    "1.0.0",
                    "2.0.0",
                    "1.1.7",
                    "99999999999999999999999.999999999999999999.99999999999999999"
            );
        }
    
        private static Stream<String> invalidVersionProvider() {
            return Stream.of(
                    "1",
                    "1.2",
                    "1.2.3-0123",
                    "+invalid",
                    "invalid",
                    "alpha",
                    "01.1.1",
                    "1.01.1",
                    "1.1.01",
                    "1.2-SNAPSHOT",
                    "1.2-RC-SNAPSHOT"
            );
        }
    
        @ParameterizedTest(name = "#{index} - Run test with Version = {0}")
        @MethodSource("validVersionProvider")
        void test_version_regex_valid(String inputVersion) {
            assertTrue(VersionUtils.isValidVersion(inputVersion));
        }
    
        @ParameterizedTest(name = "#{index} - Run test with Version = {0}")
        @MethodSource("invalidVersionProvider")
        void test_version_regex_invalid(String inputVersion) {
            assertFalse(VersionUtils.isValidVersion(inputVersion));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    3. 优先级比较

    参考:https://semver.org/lang/zh-CN/#spec-item-11

    版本的优先层级指的是不同版本在排序时如何比较。

    1. 判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号后进行比较。

    2. 由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较。

      例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。

    对应java代码及单元测试代码:

        /**
         * 比较两个版本号大小
         * version1比version2大返回1
         * version1比version2小返回-1
         * version1与version2相同返回0
         *
         * @param version1 version1
         * @param version2 version2
         * @return 比较结果
         */
        public static int compare(String version1, String version2) {
            if (!isValidVersion(version1) || !isValidVersion(version2)) {
                throw new RuntimeException("invalid version.");
            }
            if (version1.equals(version2)) {
                return 0;
            }
            String[] version1Codes = version1.split("\\.");
            String[] version2Codes = version2.split("\\.");
            for (int i = 0; i < version1Codes.length; i++) {
                int code1 = Integer.parseInt(version1Codes[i]);
                int code2 = Integer.parseInt(version2Codes[i]);
                if (code1 > code2) {
                    return 1;
                } else if (code1 < code2) {
                    return -1;
                }
            }
            return 0;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    对应单元测试代码:

        @Test
        @DisplayName("version compare return 1")
        public void test_version_compare_return_1() {
            String version1 = "1.1.1";
            String version2 = "1.1.0";
            Assertions.assertEquals(1, VersionUtils.compare(version1, version2));
            version1 = "2.1.1";
            version2 = "1.2.0";
            Assertions.assertEquals(1, VersionUtils.compare(version1, version2));
            version1 = "10.1.1";
            version2 = "2.2.0";
            Assertions.assertEquals(1, VersionUtils.compare(version1, version2));
        }
    
        @Test
        @DisplayName("version compare return -1")
        public void test_version_compare_return__1() {
            String version1 = "1.1.1";
            String version2 = "1.1.2";
            Assertions.assertEquals(-1, VersionUtils.compare(version1, version2));
            version1 = "2.1.1";
            version2 = "2.2.0";
            Assertions.assertEquals(-1, VersionUtils.compare(version1, version2));
            version1 = "10.1.1";
            version2 = "11.2.0";
            Assertions.assertEquals(-1, VersionUtils.compare(version1, version2));
        }
    
        @Test
        @DisplayName("version compare return 0")
        public void test_version_compare_return_0() {
            String version1 = "1.1.1";
            String version2 = "1.1.1";
            Assertions.assertEquals(0, VersionUtils.compare(version1, version2));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    参考

    1. 语义化版本 2.0.0,

  • 相关阅读:
    ubuntu20.04 编译内核源码5.15.58
    Oracle-数据库组件invalid问题处理
    笔者近期感想
    微信小程序 画布canvas
    虹科分享 | 集中管理的安全USB驱动器的好处
    [machine Learning]强化学习
    剑指 Offer II 061. 和最小的 k 个数对
    【INTEL(ALTERA)】Nios II软件开发人员手册中设计位置的错误示例
    无涯教程-JavaScript - LOOKUP函数
    C语言之文件操作【万字详解】
  • 原文地址:https://blog.csdn.net/Next_Second/article/details/127956160