1. ホーム
  2. regex

[解決済み] バージョン番号解析のための正規表現

2023-01-06 11:26:12

質問

以下のフォームのバージョン番号を持っています。

バージョン.リリース.モディフィケーション

ここで、version、release、modificationは数字か'*'ワイルドカード文字です。さらに、これらの数字(およびその前の.)のいずれかが欠けていてもかまいません。

したがって、以下は有効であり、次のようにパースされます。

1.23.456 = version 1, release 23, modification 456
1.23     = version 1, release 23, any modification
1.23.*   = version 1, release 23, any modification
1.*      = version 1, any release, any modification
1        = version 1, any release, any modification
*        = any version, any release, any modification

しかし、これらは有効ではありません。

*.12
*123.1
12*
12.*.34

リリース番号、バージョン番号、修正番号を検証して取得するための、あまり複雑でない正規表現をどなたか教えてください。

どのように解決するのですか?

という形式で表現します。

1-3個のドット区切りで、最後の1個が*"になることを除けば、それぞれ数字です。

正規表現としては

^(\d+\.)?(\d+\.)?(\*|\d+)$

[追記:この解決策は簡潔な検証方法ですが、値の抽出に余分な作業が必要であることが指摘されています。正規表現を複雑にすることで対処するか、マッチしたグループを処理することで対処するかは、好みの問題です。

私のソリューションでは、グループは "." 文字を捕捉してしまいます。これは、ajborley の回答のように、捕捉しないグループを使用して対処することができます。

また、右端のグループは、コンポーネントが3つ以下であっても最後のコンポーネントをキャプチャするため、例えば2コンポーネントの入力では、最初と最後のグループがキャプチャされ、真ん中のグループは未定義になります。これは、サポートされている場合、非貪欲なグループによって対処できると思います。

正規表現の後で両方の問題に対処するための Perl コードは、次のようなものになるでしょう。

@version = ();
@groups = ($1, $2, $3);
foreach (@groups) {
    next if !defined;
    s/\.//;
    push @version, $_;
}
($major, $minor, $mod) = (@version, "*", "*");

で分割するよりも短くなることはありません。 "." ]