2011-08-24 37 views
0

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

因此,现在我有一个新的文本提要,它由一个文件头,一个批头和批量下的许多详细记录组成。文件头包含文件中所有详细记录的计数,并且我被要求在分配的转换中“分割”文件,本质上为每批记录生成一个文件。这也是相当简单的,但踢球者希望更新每个文件的文件头以反映细节计数。

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

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

我被要求举个例子。说我有一个文件,像这样:

FILE001DETAILCOUNT002 
BATCH01 
DETAIL001FOO 
BATCH02 
DETAIL001BAR 

这个文件将被分割并存储在两个位置。该文件将是这样的:

FILE001DETAILCOUNT001 
BATCH01 
DETAIL001FOO 

FILE001DETAILCOUNT001 
BATCH01 
DETAIL001BAR 

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

+0

认真吗?没有接受者? –

+0

你可以添加一些清晰的例子。 “我想把'这'变成'那个'”。我认为'Regex.Replace'的'MatchEvaluator'重载可能有帮助,但我不确定我是否理解你的问题。 –

+0

在任何情况下,如果您的输入不是XML,请远离XSLT。 – driis

回答

1

自己正则表达式不能指望比赛他们已经取得了数(或,最好把他们不公开,为正则表达式的用户),所以你确实需要额外的程序代码来跟踪这一点。

正则表达式只能捕获源文件中某处存在的文本,它不能生成新文本。所以,除非你能够在源头的某个位置明确地找到需要的数字,否则你运气不好。抱歉。

+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 
+0

不幸的是,这不是纯粹的正则表达式;这是C#,这是我需要假装我没有访问。 –

+0

所以你想要一个正则表达式成为整个程序? 如果这样看看http://en.wikipedia.org/wiki/AWK 虽然我的建议是编写一个脚本,如上所述进行分析和转换。更容易维护! –

+0

绝对没问题。这是一个圆孔中的方形钉,但如果可能的话,这是最糟糕的选择。 –