Reputation: 1295
I'm using a regular expression replace (in a .Net application) to create an item id from a barcode. Here's the regex I'm using:
^(?<Bestellnr>\w{6})(?<Pos>\d{3})M(?<Menge>\d{5})P(?<Lfd>\d{3})$
The replacement string is (it has leading blanks, but that's not important here):
${Bestellnr}${Pos} ${Lfd}
An example input would be:
685774010M00555P002
The current result of the above replacement is:
685774010 002
But now my customer wants me to remove the leading zeroes from the groups "Pos" and "Lfd", so the result should change to:
685774 10 2
Edit: Please note that the two zeroes in the "lfd" group are replaced by two blanks!
I've tried for hours now, but I cannot seem to get this working. Best approach I was able to find was to create extra groups for the leading zeroes like:
^(?<Bestellnr>\w{6})(?<PosNull>0*)(?<Pos>\d{1,})M(?<Menge>\d{5})P(?<LfdNull>0*)(?<Lfd>\d{1,})$
But I don't know how I can replace the "null groups" with the correct number of blanks. Is this possible at all? (Until now I thought there's nothing that's not possible with Regex ;-)
Can anyone help?
Upvotes: 3
Views: 473
Reputation: 1295
Ok, found a solution that fits my needs. It's done with a simple String.Format, passing it the Groups of the Regex converted to ints. Groups are accessed by index, but since it's done in the format string, no hardcoding is required.
Here's the code:
// both from app.config
Regex regex = new Regex(@"(?<Bestellnr>\w{6})(?<Pos>\d{3})M(?<Menge>\d{5})P(?<Lfd>\d{3})");
string format = " {0,6:d}{1,3:d} {3,3:d}";
string barcode = "685774010M00555P002";
Match match = regex.Match(barcode);
if (match.Success)
{
var groups = (from Group grp in match.Groups select grp.Value).Skip(1).Select(x => (object)int.Parse(x)).ToArray();
string s = string.Format(format, groups);
Console.WriteLine(s);
}
Remarks:
Upvotes: 0
Reputation: 2852
try this:
string input = "685774010M00555P002";
input = Regex.Replace(input,
@"^(?<Bestellnr>\w{6})0*(?<Pos>\d{1,3})M(?<Menge>\d{5})P0*(?<Lfd>\d{1,3})$",
m => m.Groups["Bestellnr"].Value +
m.Groups["Pos"].Value.PadLeft(3, ' ') +
m.Groups["Lfd"].Value.PadLeft(4, ' '));
result:
input = "685774 10 2"
Edit: Kept the same regex as before but changed the replace
Another Edit:
You can remove the group names completely and refer to them by number:
input = Regex.Replace(input,
@"^(\w{6})0*(\d{1,3})M(\d{5})P0*(\d{1,3})$",
m => m.Groups[1].Value +
m.Groups[2].Value.PadLeft(3, ' ') +
m.Groups[4].Value.PadLeft(4, ' '));
Note: m.Groups[0]
refers to the entire match
Upvotes: 2
Reputation: 32787
You can do it by replacing 0's with space using matchevaluator
!
Regex.Replace("685774010M00555P002",
@"^(?<Bestellnr>\w{6})(?<Pos>\d{3})M(?<Menge>\d{5})P(?<Lfd>\d{3})$",
m=>m.Groups["Bestellnr"].Value+""+
Regex.Replace(m.Groups["Pos"].Value,"(?<=^0*)0"," ")+
" "+
Regex.Replace(m.Groups["Lfd"].Value,"(?<=^0*)0"," "));
Upvotes: 2