我需要从字符串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
答案 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";
}