1

version次の単純なルールを使用して、文字列 (sql varchar(3) のような最大 3 文字の「次のバージョン」)から取得する必要があります。

最後の文字が数値を構成する場合はインクリメントし、常に最大 3 文字に収まる場合はそのままにします。

"Hi1" => "Hi2"、"H9" => "H10" と言いますが、"xx9" は変更されません。

  Public Shared Function GetNextVersion(oldVersion As String) As String
    Dim newVersion As String = String.Empty
    If Regex.IsMatch(oldVersion, "?????") Then
      Return newVersion
    Else
      Return oldVersion
    End If
  End Function
4

2 に答える 2

3

これが正規表現になります。文字のグループの後に数字のグループが続くものと一致します。

Public Dim regex As Regex = New Regex( _
      "^(?<prefix>.*?0*)(?<version>\d+)$", _
      RegexOptions.IgnoreCase _
        Or RegexOptions.CultureInvariant _
        Or RegexOptions.Compiled _
    )

これには、最初の文字である「プレフィックス」とバージョンを含む「バージョン」という 2 つの名前付きキャプチャ グループが含まれます。

バージョンを int にキャストしてインクリメントし、プレフィックスと新しいバージョンを連結して新しいバージョン番号を返します。

だから、あなたはこのようなもので終わるでしょう

Public versionRegex As Regex = New Regex( _
   "^(?<prefix>.*?0*)(?<version>\d+)$", _
   RegexOptions.IgnoreCase _
     Or RegexOptions.CultureInvariant _
     Or RegexOptions.Compiled _
 )

Public Shared Function GetNextVersion(oldVersion As String) As String
    Dim matches = versionRegex.Matches(oldVersion)
    If (matches.Count <= 0) Then
        Return oldVersion
    End If

    Dim match = matches(0)
    Dim prefix = match.Groups.Item("prefix").Value
    Dim version = CInt(match.Groups.Item("version").Value)

    Return String.Format("{0}{1}", prefix, version + 1)
End Function
于 2012-09-28T15:23:32.353 に答える
0

私は正規表現を使用し
ませ

戦略はパフォーマンスです。
エッジケースをテストする必要があり、たくさんあります。
まずは安いものから。
明らかにこれはC#です

すべてのテストケースを取得したと思います。

static void Main(string[] args)
    {
        System.Diagnostics.Debug.WriteLine(NewVer("H"));
        System.Diagnostics.Debug.WriteLine(NewVer("Hi"));
        System.Diagnostics.Debug.WriteLine(NewVer("Hii"));
        System.Diagnostics.Debug.WriteLine(NewVer("Hiii"));
        System.Diagnostics.Debug.WriteLine(NewVer("H1"));
        System.Diagnostics.Debug.WriteLine(NewVer("H9"));
        System.Diagnostics.Debug.WriteLine(NewVer("Hi1"));
        System.Diagnostics.Debug.WriteLine(NewVer("H19"));
        System.Diagnostics.Debug.WriteLine(NewVer("9"));
        System.Diagnostics.Debug.WriteLine(NewVer("09"));
        System.Diagnostics.Debug.WriteLine(NewVer("009"));
        System.Diagnostics.Debug.WriteLine(NewVer("7"));
        System.Diagnostics.Debug.WriteLine(NewVer("07"));
        System.Diagnostics.Debug.WriteLine(NewVer("27"));
        System.Diagnostics.Debug.WriteLine(NewVer("347"));
        System.Diagnostics.Debug.WriteLine(NewVer("19"));
        System.Diagnostics.Debug.WriteLine(NewVer("999"));
        System.Diagnostics.Debug.WriteLine(NewVer("998"));
        System.Diagnostics.Debug.WriteLine(NewVer("C99"));
        System.Diagnostics.Debug.WriteLine(NewVer("C08"));
        System.Diagnostics.Debug.WriteLine(NewVer("C09"));
        System.Diagnostics.Debug.WriteLine(NewVer("C11"));
    }

    public static string NewVer(string oldVer)
    {
        string newVer = oldVer.Trim();
        if (string.IsNullOrEmpty(newVer)) return oldVer;
        if (newVer.Length > 3) return oldVer;
        // at this point all code paths need char by postion
        // regex is not the appropriate tool
        Char[] chars = newVer.ToCharArray();
        if (!char.IsDigit(chars[chars.Length - 1])) return oldVer;
        byte lastDigit = byte.Parse(chars[chars.Length - 1].ToString());
        if (lastDigit != 9)
        {
            lastDigit++;
            StringBuilder sb = new StringBuilder();
            for (byte i = 0; i < chars.Length - 1; i++)
            {
                sb.Append(chars[i]);
            }
            sb.Append(lastDigit.ToString());
            return sb.ToString();
        }
        // at this point the last char is 9  and lot of edge cases 
        if (chars.Length == 1) return (lastDigit + 1).ToString();
        if (char.IsDigit(chars[chars.Length - 2]))
        {
            if (chars.Length == 2) return ((byte.Parse(newVer)) + 1).ToString();
            byte nextToLastDigit = byte.Parse(chars[chars.Length - 2].ToString());
            if (nextToLastDigit == 9)
            {
                if (char.IsDigit(chars[0]))
                {
                    byte firstOfthree = byte.Parse(chars[0].ToString());
                    if (firstOfthree == 9) return oldVer; // edge case 999
                    // all three digtis and not 999
                    return ((byte.Parse(newVer)) + 1).ToString();
                }
                // have c99
                return oldVer;
            }
            else
            {
                //have c 1-8 9 
                return chars[0].ToString() + (10 * nextToLastDigit + lastDigit + 1).ToString();        
            }
        }
        // at this point have c9 or cc9
        if (chars.Length == 3) return oldVer;
        // at this point have c9
        return chars[0].ToString() + "10";
    }
于 2012-09-28T15:05:29.943 に答える