PHP
JavaScript
正規表現

バージョニング方法、バージョンの前後関係チェックについて

バージョンの値が正しいかどうかをチェックする正規表現です。

バージョンとは

アプリやWebサービスをリリースするときに付与する値のことです。
例えば、2017年12月4日時点のChromeの最新バージョンは 62.0.3202.94 となっています。

バージョニング方法

バージョンというのは以前のバージョンよりも小さい値を小さい値を設定してはいけません。
これは、ユーザの誤解を招くとともに、バージョン管理という概念が崩れてしまいます。
たとえ中身を前の状態に戻す場合であっても、バージョンの値は以前よりも大きい値を付ける必要があります。

また、バージョンの形式も同じである必要があります。
形式とは、ピリオドによる区切られ方 のことです。
例えば、現在のバージョンが 1.0.0 であるとき、次のバージョンは 1.0.12.0.0 のように、同じ形式である必要があります。2.0などにしてはいけません。

このあたりの話は、 セマンティックバージョニング と呼ばれるバージョンの付け方のドキュメントにわかりやすく書かれています。
セマンティック バージョニング 2.0.0 | Semantic Versioning

正規表現

バージョンの付け方には上記のセマンティックバージョニング以外にも色々あると思いますが、一般的には数値を幾つかのピリオドで区切った形になります。
区切られた値は0以上の整数値です。(NG: 1.001.1)
ピリオドは先頭と末尾には使用できません。連続で使用することもできません。(NG: 1.2.3..4、2.2.5.)
上記を満たす正規表現が下記になります。

/^([0-9]|[1-9][0-9]{1,})(\.([0-9]|[1-9][0-9]{1,}))*$/

前後関係のチェック

新しいバージョンが現在のバージョンより小さい値になっていないか、形式は同じか、をチェックしたいというときに使うスクリプトです。

PHP版

/**
 * @param string $new_version // 新しいバージョン
 * @param string $current_version // 現在のバージョン
 * @return bool
 */
public function checkVersion($new_version, $current_version)
{
    // 形式チェック
    if (substr_count($new_version, '.') != substr_count($current_version, '.'))
    {
        echo '形式が違う';
        return false;
    }

    // 前後関係チェック
    $new_version_arr = explode('.', $new_version);
    $current_version_arr = explode('.', $current_version);

    $chk_tmp_new = "";
    $chk_tmp_curr = "";
    for ($i = 0; $i < count($new_version_arr); $i++)
    {
        $chk_tmp_new = $new_version_arr[$i];
        $chk_tmp_curr = $current_version_arr[$i];

        if ($i === count($new_version_arr) - 1)
        {
            if ((int)$chk_tmp_new >= (int)$chk_tmp_curr)
            {
                return true;
            }
        }
        else
        {
            if ((int)$chk_tmp_new > (int)$chk_tmp_curr)
            {
                return true;
            }
            else if ((int)$chk_tmp_new < (int)$chk_tmp_curr)
            {
                echo '新しいバージョンのほうが小さい';
                return false;
            }
        }
    }

    return false;
}

javascript版

/**
 * @param string new_version // 新しいバージョン
 * @param string current_version // 現在のバージョン
 * @return bool
 */
function CheckVersion(new_version, current_version) {
    // 形式チェック
    if (new_version.split(".").length != current_version.split(".").length) {
        console.log("形式が違う");
        return false;
    }

    // 前後関係チェック
    var new_version_arr = new_version.split(".");
    var current_version_arr = current_version.split(".");

    var chk_tmp_new = "";
    var chk_tmp_curr = "";
    for (var i = 0; i < new_version_arr.length; i++) {
        chk_tmp_new = parseInt(new_version_arr[i], 10);
        chk_tmp_curr = parseInt(current_version_arr[i], 10);

        if (i == new_version_arr.length - 1) {
            if (chk_tmp_new >= chk_tmp_curr) {
                return true;
            }
        } else {
            if (chk_tmp_new < chk_tmp_curr) {
                console.log("新しいバージョンのほうが小さい");
                return false;
            } else if (chk_tmp_new > chk_tmp_curr) {
                return true;
            }
        }
    }

    return false;
}