102

次の形式のバージョン番号があります。

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

リリース、バージョン、および変更番号を検証および取得するための、それほど複雑ではない正規表現を誰かが私に提供できますか?

4

23 に答える 23

116

形式を次のように表現します。

"1 ~ 3 個のドットで区切られたコンポーネント。最後のものを除く各数値は *"

正規表現として、それは次のとおりです。

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

[編集して追加: このソリューションは検証するための簡潔な方法ですが、値を抽出するには余分な作業が必要であることが指摘されています。正規表現を複雑にするか、一致したグループを処理することでこれに対処するかは好みの問題です。

私のソリューションでは、グループがキャラクターをキャプチャし"."ます。これは、ajborley の回答のように、非キャプチャ グループを使用して処理できます。

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

正規表現の後に両方の問題を処理する Perl コードは次のようになります。

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

で分割するよりも実際には短くはありません"." ]

于 2008-09-17T11:33:02.467 に答える
41

正規表現を使用すると、2つの問題が発生します。ドット( "。")で分割し、各部分がワイルドカードまたは数字のセットのいずれかであることを確認します(正規表現は今では完璧です)。物事が有効な場合は、分割の正しいチャンクを返すだけです。

于 2008-09-17T11:24:42.143 に答える
14

すべての応答に感謝します! これはエースです:)

OneByOne の回答 (私には最も単純に見えた) に基づいて、いくつかの非キャプチャ グループ (「(?:」の部分 - 非キャプチャ グループを紹介してくれた VonC に感謝します!) を追加したので、キャプチャのみを行うグループ数字または * 文字が含まれています。

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

どうもありがとうございました!

于 2008-09-17T12:13:01.793 に答える
13

これはうまくいくかもしれません:

^(\*|\d+(\.\d+){0,2}(\.\*)?)$

トップレベルでは、「*」は有効なバージョン番号の特殊なケースです。それ以外の場合は、数字で始まります。次に、0、1、または2つの「.nn」シーケンスがあり、その後にオプションの「。*」が続きます。この正規表現は1.2.3。*を受け入れますが、これはアプリケーションで許可される場合と許可されない場合があります。

一致したシーケンス、特に(\.\d+){0,2}パーツを取得するためのコードは、特定の正規表現ライブラリによって異なります。

于 2008-09-17T11:16:12.947 に答える
12

私の 2 セント: このシナリオがありました: 文字列リテラルからバージョン番号を解析する必要がありました。(これは元の質問とは大きく異なることは知っていますが、バージョン番号を解析するための正規表現を見つけるためにグーグルで検索すると、このスレッドが一番上に表示されたので、ここにこの回答を追加してください)

したがって、文字列リテラルは次のようになります。「サービス バージョン 1.2.35.564 が実行中です!」

このリテラルから 1.2.35.564 を解析する必要がありました。@ajborley からヒントを得て、私の正規表現は次のとおりです。

(?:(\d+)\.)?(?:(\d+)\.)?(?:(\d+)\.\d+)

これをテストするための小さな C# スニペットは次のようになります。

void Main()
{
    Regex regEx = new Regex(@"(?:(\d+)\.)?(?:(\d+)\.)?(?:(\d+)\.\d+)", RegexOptions.Compiled);

    Match version = regEx.Match("The Service SuperService 2.1.309.0) is Running!");
    version.Value.Dump("Version using RegEx");   // Prints 2.1.309.0        
}
于 2014-12-18T06:55:20.830 に答える
8

使用しているプラ​​ットフォームはわかりませんが、.NETには、「nnnn」バージョン番号を解析するSystem.Versionクラスがあります。

于 2008-09-17T11:52:32.873 に答える
6

私は分割の提案に同意する傾向があります。

問題の「テスター」を perl で作成しました

#!/usr/bin/perl -w


@strings = ( "1.2.3", "1.2.*", "1.*","*" );

%regexp = ( svrist => qr/(?:(\d+)\.(\d+)\.(\d+)|(\d+)\.(\d+)|(\d+))?(?:\.\*)?/,
            onebyone => qr/^(\d+\.)?(\d+\.)?(\*|\d+)$/,
            greg => qr/^(\*|\d+(\.\d+){0,2}(\.\*)?)$/,
            vonc => qr/^((?:\d+(?!\.\*)\.)+)(\d+)?(\.\*)?$|^(\d+)\.\*$|^(\*|\d+)$/,
            ajb => qr/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/,
            jrudolph => qr/^(((\d+)\.)?(\d+)\.)?(\d+|\*)$/
          );

  foreach my $r (keys %regexp){
    my $reg = $regexp{$r};
    print "Using $r regexp\n";
foreach my $s (@strings){
  print "$s : ";

    if ($s =~m/$reg/){
    my ($main, $maj, $min,$rev,$ex1,$ex2,$ex3) = ("any","any","any","any","any","any","any");
    $main = $1 if ($1 && $1 ne "*") ;
    $maj = $2 if ($2 && $2 ne "*") ;
    $min = $3 if ($3 && $3 ne "*") ;
    $rev = $4 if ($4 && $4 ne "*") ;
    $ex1 = $5 if ($5 && $5 ne "*") ;
    $ex2 = $6 if ($6 && $6 ne "*") ;
    $ex3 = $7 if ($7 && $7 ne "*") ;
    print "$main $maj $min $rev $ex1 $ex2 $ex3\n";

  }else{
  print " nomatch\n";
  }
  }
print "------------------------\n";
}

現在の出力:

> perl regex.pl
Using onebyone regexp
1.2.3 : 1. 2. 3 any any any any
1.2.* : 1. 2. any any any any any
1.* : 1. any any any any any any
* : any any any any any any any
------------------------
Using svrist regexp
1.2.3 : 1 2 3 any any any any
1.2.* : any any any 1 2 any any
1.* : any any any any any 1 any
* : any any any any any any any
------------------------
Using vonc regexp
1.2.3 : 1.2. 3 any any any any any
1.2.* : 1. 2 .* any any any any
1.* : any any any 1 any any any
* : any any any any any any any
------------------------
Using ajb regexp
1.2.3 : 1 2 3 any any any any
1.2.* : 1 2 any any any any any
1.* : 1 any any any any any any
* : any any any any any any any
------------------------
Using jrudolph regexp
1.2.3 : 1.2. 1. 1 2 3 any any
1.2.* : 1.2. 1. 1 2 any any any
1.* : 1. any any 1 any any any
* : any any any any any any any
------------------------
Using greg regexp
1.2.3 : 1.2.3 .3 any any any any any
1.2.* : 1.2.* .2 .* any any any any
1.* : 1.* any .* any any any any
* : any any any any any any any
------------------------
于 2008-09-17T11:46:33.513 に答える
5
^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$

おそらくもっと簡潔なものは次のようになります:

^(?:(\d+)\.){0,2}(\*|\d+)$

次に、これを1.2.3.4.5。*に拡張するか、{0,2}の代わりに*または{2}を使用してXYZに正確に制限することができます。

于 2008-09-17T12:30:27.400 に答える
5

これは、あなたが規定したものに対して機能するはずです。ワイルドカードの位置に依存し、ネストされた正規表現です。

^((\*)|([0-9]+(\.((\*)|([0-9]+(\.((\*)|([0-9]+)))?)))?))$

http://imgur.com/3E492.png

于 2010-04-12T03:28:59.063 に答える
4

別の試み:

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

これにより、グループ 4、5、6 の 3 つのパーツが得られますが、これらは右に配置されています。したがって、4、5、または 6 の最初の非 null はバージョン フィールドを示します。

  • 1.2.3 は 1,2,3 を与える
  • 1.2.* は 1,2,* を返します
  • 1.2 は null,1,2 を返します
  • *** null,null,* を与える
  • 1.* は null,1,* を返します
于 2008-09-17T12:17:51.050 に答える
3
(?ms)^((?:\d+(?!\.\*)\.)+)(\d+)?(\.\*)?$|^(\d+)\.\*$|^(\*|\d+)$

最初の6つの例と完全に一致し、他の4つの例を拒否します

  • グループ1:メジャーまたはmajor.minorまたは'*'
  • 存在する場合はグループ2:マイナーまたは*
  • 存在する場合はグループ3:*

'(?ms)'を削除できます。これを使用して、 QuickRex
を介して複数行に適用されるこの正規表現を示しました。

于 2008-09-17T11:47:56.287 に答える
3

XSD 要素の指定:

<xs:simpleType>
    <xs:restriction base="xs:string">
        <xs:pattern value="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\..*)?"/>
    </xs:restriction>
</xs:simpleType>
于 2016-12-28T15:17:01.520 に答える
3

あなたが望むことを正確に行う正規表現を持つことはかなり難しいようです (つまり、必要なケースのみを受け入れ、他のすべてを拒否し、3 つのコンポーネントのいくつかのグループ返します)。私はそれを試してみて、これを思いつきました:

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

IMO (私は広範囲にテストしていません) これは入力のバリデーターとしてうまく機能するはずですが、問題はこの正規表現がコンポーネントを取得する方法を提供しないことです。そのためには、期間を分割する必要があります。

このソリューションはオールインワンではありませんが、プログラミングではほとんどの場合必要ありません。もちろん、これはコードに含まれる可能性のある他の制限に依存します。

于 2008-09-17T12:19:34.133 に答える
3

これは 1.2.3.* にも一致します。

^(*|\d+(.\d+){0,2}(.*)?)$

私はあまりエレガントではないことを提案します:

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

于 2008-09-17T12:00:20.437 に答える
3

regexp は貪欲であることに注意してください。したがって、バージョン番号文字列内だけを検索し、より大きなテキスト内を検索しない場合は、^ と $ を使用して文字列の開始と終了をマークします。Greg の正規表現は問題なく動作するようですが (私のエディターで簡単に試してみました)、ライブラリ/言語によっては、最初の部分が間違ったバージョン番号内の "*" に一致する場合があります。正規表現を 1 年ほど使用していないため、何か不足している可能性があります。

これにより、正しいバージョン番号のみを見つけることができるようになります。

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

編集:実際、グレッグはすでにそれらを追加し、彼のソリューションを改善しました。私は遅すぎます:)

于 2008-09-17T11:39:44.153 に答える
0
/^([1-9]{1}\d{0,3})(\.)([0-9]|[1-9]\d{1,3})(\.)([0-9]|[1-9]\d{1,3})(\-(alpha|beta|rc|HP|CP|SP|hp|cp|sp)[1-9]\d*)?(\.C[0-9a-zA-Z]+(-U[1-9]\d*)?)?(\.[0-9a-zA-Z]+)?$/
  • 通常バージョン:([1-9]{1}\d{0,3})(\.)([0-9]|[1-9]\d{1,3})(\.)([0-9]|[1-9]\d{1,3})
  • プレリリース版またはパッチ適用済みバージョン: (\-(alpha|beta|rc|EP|HP|CP|SP|ep|hp|cp|sp)[1-9]\d*)? (エクステンション パック、ホットフィックス パック、クールフィックス パック、サービス パック)
  • カスタマイズされたバージョン:(\.C[0-9a-zA-Z]+(-U[1-9]\d*)?)?
  • 内部バージョン:(\.[0-9a-zA-Z]+)?

ここに画像の説明を入力

于 2022-01-04T07:41:18.443 に答える