3

我正在使用正则表达式替换(在 .Net 应用程序中)从条形码创建项目 ID。这是我正在使用的正则表达式:

^(?<Bestellnr>\w{6})(?<Pos>\d{3})M(?<Menge>\d{5})P(?<Lfd>\d{3})$

替换字符串是(它有前导空格,但这在这里并不重要):

${Bestellnr}${Pos} ${Lfd}

一个示例输入是:

685774010M00555P002

上述替换的当前结果是:

685774010 002

但是现在我的客户希望我从“Pos”和“Lfd”组中删除前导零,因此结果应该更改为:

685774 10   2

编辑:请注意,“lfd”组中的两个零被两个空格替换!

我已经尝试了几个小时,但我似乎无法让它工作。我能找到的最佳方法是为前导零创建额外的组,例如:

^(?<Bestellnr>\w{6})(?<PosNull>0*)(?<Pos>\d{1,})M(?<Menge>\d{5})P(?<LfdNull>0*)(?<Lfd>\d{1,})$

但我不知道如何用正确数量的空白替换“空组”。这可能吗?(直到现在,我认为 Regex 没有什么是不可能的 ;-)

任何人都可以帮忙吗?

4

3 回答 3

2

试试这个:

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, ' '));

结果:

input = "685774 10   2"

编辑: 保持与以前相同的正则表达式,但更改了替换

另一个编辑:

您可以完全删除组名并按编号引用它们:

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, ' '));

注:m.Groups[0]指整场比赛

于 2012-12-05T11:46:31.837 回答
2

您可以通过使用空格替换 0 来做到这一点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"," "));
于 2012-12-05T11:56:20.213 回答
0

好的,找到了适合我需求的解决方案。它是通过一个简单的 String.Format 完成的,将 Regex 的 Groups 传递给它转换为 int。组通过索引访问,但由于它是在格式字符串中完成的,因此不需要硬编码。

这是代码:

// 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);
}

评论:

  • Skip(1) 是必要的,因为集合中的第一组是完整匹配本身。
  • 强制转换为 object 是必需的,因为 string.format 需要一个 params object[] 数组并且不能与 int[] 一起使用
于 2012-12-06T14:48:50.153 回答