Increment a number within a string (C#)
I have a string with a number at the end, after a dash ("-"). I'd like开发者_运维百科 to create that same string with that number incremented by 1. Pretty simple, but I'm wondering if there's a better approach to this? Thanks!
string oldString = "BA-0001-3";
int lastIndex = oldString.LastIndexOf("-");
string oldNumber = oldString.SubString(lastIndex + 1);
string oldPartialString = oldString.SubString(0, lastIndex);
int newNumber = Convert.ToInt32(oldNumber) + 1;
string newString = oldPartialString + newNumber.ToString();
Regex?
Example:
Regex.Replace("BA-0001-3", @"[A-Z]{2}-\d{4}-(\d+)",
m => (Convert.ToInt32(m.Groups[1].Value) + 1).ToString())
I would probably use my friend string.Split
:
string oldString = "BA-0001-3";
string[] parts = oldString.Split('-');
parts[parts.Length-1] = (Convert.ToInt32(parts[parts.Length-1])+1).ToString();
string newString = string.Join("-", parts);
A small tweak that will perhaps make it quicker (by accessing parts.Length
and subtracting 1 only once - didn't profile so it's purely a guess, and it is likely a marginal difference anyway), but above all more robust (by using int.TryParse
):
string oldString = "BA-0001-3";
string[] parts = oldString.Split('-');
int number;
int lastIndex = parts.Length-1;
parts[lastIndex] = (int.TryParse(parts[lastIndex], out number) ? ++number : 1).ToString();
string newString = string.Join("-", parts);
Updated per Ahmad Mageed's comments below. This is his answer much more than it is mine now :-)
I would do it the way you have it now, but for fun wanted to see if I could do it with linq.
var x = "BA-0001-3".Split('-');
var y = x.First() + "-" + x.ElementAt(1) + "-" + (Convert.ToInt32(x.Last()) + 1);
This works in LINQPad.
Edit: Obviously I'm not a pro with linq. Hopefully there will be other answers/comments on how this can be improved.
Here's an example of how it could be done with RegEx:
public void Test()
{
System.Text.RegularExpressions.Regex rx = new Regex(@"(?<prefix>.*\-)(?<digit>\d+)");
string input = "BA-0001-3";
string output = string.Empty;
int digit = 0;
if (int.TryParse(rx.Replace(input, "${digit}"), out digit))
{
output = rx.Replace(input, "${prefix}" + (digit + 1));
}
Console.WriteLine(output);
}
Using the regex (which already seems to have now been filled in with more details) I end up with something like:
var regex = new Regex(@"^(?<Category>[A-Za-z]{1,2})-(?<Code>[0-9]{4})-(?<Number>[0-9]+)$");
var newCode = regex.Replace("BA-0001-3", new MatchEvaluator(ReplaceWithIncrementedNumber));
Where the MatchEvaluator function is:
public static string ReplaceWithIncrementedNumber(Match match)
{
Debug.Assert(match.Success);
var number = Int32.Parse(match.Groups["Number"].Value);
return String.Format("{0}-{1}-{2}", match.Groups["Category"].Value, match.Groups["Code"].Value, number + 1);
}
Here is an example of a class that exposes the three parts of your "part number". Not particularly fancy (also note the absence of error checking/validation).
class Program
{
static void Main(string[] args)
{
PartNumber p1 = new PartNumber("BA-0001-3");
for (int i = 0; i < 5; i++)
{
p1.Sub++;
Debug.WriteLine(p1);
}
PartNumber p2 = new PartNumber("BA", 2, 3);
for (int i = 0; i < 5; i++)
{
p2.Sub++;
Debug.WriteLine(p2);
}
}
}
class PartNumber
{
public PartNumber(string make, int model, int sub)
{
Make = make;
Model = model;
Sub = sub;
}
public PartNumber(string part)
{
//Might want to validate the string here
string [] fields = part.Split('-');
//Are there 3 fields? Are second and third fields valid ints?
Make = fields[0];
Model = Int32.Parse(fields[1]);
Sub = Int32.Parse(fields[2]);
}
public string Make { get; set; }
public int Model { get; set; }
public int Sub { get; set; }
public override string ToString()
{
return string.Format("{0}-{1:D4}-{2}", Make, Model, Sub);
}
}
精彩评论