元正则表达式?

时间:2011-08-24 13:45:30

标签: c# regex xslt

前段时间我写了一个文件路由实用程序(.NET)来检查文件的位置和名称模式,并根据匹配将其移动到其他预先配置的位置。相当简单,直截了当的东西。我通过一系列可以分配给文件“route”的正则表达式搜索和替换操作包含了次要转换的可能性,目的是添加标题行,用管道替换逗号,等等。 / p>

所以现在我有了一个新的文本提要,它包含文件头,批处理标题和批次下的大量详细记录。文件头包含文件中所有详细记录的计数,并且我被要求在分配的转换中“拆分”文件,基本上为每个批记录生成一个文件。这也是相当简单的,但是需要更新每个文件的文件头以反映细节计数。

我甚至不知道纯正则表达式是否可行。我可以计算给定文本文档中组的匹配数并替换原始文本中的计数值,或者我是否必须为这个文件编写自定义转换器?

如果我必须编写另一个变压器,是否有关于如何使其通用到可重复使用的建议?我正在考虑添加一个XSLT转换器选项,但我对XSLT的理解并不是那么好。

我被问到一个例子。说我有这样的文件:

FILE001DETAILCOUNT002
BATCH01
DETAIL001FOO
BATCH02
DETAIL001BAR

此文件将被拆分并存储在两个位置。文件如下所示:

FILE001DETAILCOUNT001
BATCH01
DETAIL001FOO

FILE001DETAILCOUNT001
BATCH01
DETAIL001BAR

所以我的贴纸是文件头的DETAILCOUNT值。

2 个答案:

答案 0 :(得分:1)

我的程序首先将文本分成几批。

我认为你会同意重新测序细节数是最棘手的部分。你可以使用MatchEvaluator委托来完成它。

Regex.Replace (
   text, // the text replace part of
   @"(?<=^DETAIL)\d+", // the regex pattern to find.
   m => (detailNum++).ToString ("000"), // replacement (evaluated for each match)
   RegexOptions.Multiline);

查看前一代码在每批开始时如何递增detailNum

  var contents = 
@"FILE001DETAILCOUNT002
BATCH01
DETAIL001FOO
BATCH02
DETAIL001BAR";

  // foreach batch....
  foreach (Match match in Regex.Matches (contents, @"BATCH\d+\s+(?:(?!BATCH\d+).*\s*)+"))
  {
     Console.WriteLine ("==============\r\nFile\r\n================");
     int batchNum = 1;
     int detailNum = 1;
     StringBuilder temp = new StringBuilder ();
     TextWriter file = new StringWriter (temp);
     // Your file here instead of my stringBuilder/StringWriter

     string batchText = match.Value;
     int count = Regex.Matches (batchText, @"^DETAIL\d+", RegexOptions.Multiline).Count;
     file.WriteLine ("FILE001DETAILCOUNT{0:000}", count);
     string newText = Regex.Replace (batchText, @"(?<=^BATCH)\d+", batchNum.ToString ("000"), RegexOptions.Multiline);
     newText = Regex.Replace (
        newText, 
        @"(?<=^DETAIL)\d+", 
        m => (detailNum++).ToString ("000"), // replacement (evaluated for each match)
        RegexOptions.Multiline);
     file.Write (newText);

     Console.WriteLine (temp.ToString ());
  }

打印

==============
File
================
FILE001DETAILCOUNT001
BATCH001
DETAIL001FOO

==============
File
================
FILE001DETAILCOUNT001
BATCH001
DETAIL001BAR

答案 1 :(得分:1)

正则表达式本身无法计算他们所做的匹配数量(或者更好的是,他们不会将其暴露给正则表达式用户),因此您需要额外的程序代码跟踪这个。

正则表达式只能捕获源材料中某处存在的文本,它无法生成新文本。因此,除非您能够在源代码中的某个位置明确找到您需要的号码,否则您将失去运气。遗憾。