获取下一个“版本”(.NET Regex)

时间:2012-09-28 14:20:46

标签: c# .net regex vb.net

我需要从字符串version(最多3个字符,如sql varchar(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

2 个答案:

答案 0 :(得分:3)

这将是你的正则表达式,它将匹配任何字母后跟一组数字。

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

它将包含两个命名的捕获组,“prefix”是初始字符,“version”包含您的版本。

将版本转换为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

答案 1 :(得分:0)

我不会使用正则表达式 正则表达式是一个解析器,这比解析左边更具逻辑性 对于3个字符,正则表达式并不比蛮力更快

战略就是表现 必须测试边缘情况,并且有很多 先做便宜的东西。
显然这是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";
    }