2011-08-24 44 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

絕對沒問題。這是一個圓孔中的方形釘,但如果可能的話,這是最糟糕的選擇。 –