2011-03-02 43 views
0

我正在尋找一種方式來使用正則表達式從兩個不同的表情的捕捉組,並將其用於搜索,並在一個單一的字符串替換與捕捉共享兩次替換之間。使用RegEx.Replace從兩個表達式替換捕捉比賽

例如:

string input_a = "abc-def-ghi"; 
string input_b = "123-4567-89"; 

string pattern_a = "(?<first>def)"; // captures 'def' from input_a and 
            // names the capture as 'first' 
string pattern_b = "(?<second>456)"; // captures '456' from input_b and 
            // names the capture as 'second' 

string translation_a = "A=${first}${second}"; // replacement strings use the named 
string translation_b = "B=${second}${first}"; // captures from both RegExs 

// I want the results of the replace to give: 

Console.Write("Result A: abc-A=def456-ghi"); // result of regex search and replace 
              // matches on 'def' and replaces this 
              // with 'A=' followed by 'def' from the 
              // first expression and '456' from the 
              // second expression 

Console.Write("Result B: 123-B=456def-789"); // same thing again but the other way 
              // around 

我的輸入/圖案/翻譯都在運行時不會被稱爲它們是用戶可配置的,並存儲在數據庫中。

任何人都可以提出一個整潔優雅的方式來做到這一點?

UPDATE

爲了讓多一點背景下我的問題,這裏是一個活生生的例子。我在處理傳入呼叫的​​電信系統中使用它。在呼叫進入時,它們有兩個信息:撥號號碼(在DDI處已知)和呼叫號碼(稱爲CLI)。

我使用存儲在數據庫中,這實際上是一組正則表達式的「規則」列表中創建一個非常動態的配置方式需要路由號碼系統。規則需要通過GUI進行更新,所以任何東西都不能進行硬編碼。

系統的這部分確實對來電一種預路由翻譯。一些例子包括(這是所有虛擬數據):

DDI    CLI 
80
415080
123402077000000 01373000003 

我需要調用「對方出來」與他們的DDI和CLI翻譯。我的數據庫包含:DDISearchPattern,DDITranslation,CLISearchPattern,CLITranslation。

我的第一個簡單的規則就是:

DDISearchPattern = "^0?(?<ddi>\d{9})$" 
DDITranslation = "0${ddi}" 
CLISearchPattern = "^0?(?<cli>\d{9})$" 
CLITranslation = "0${cli}" 

有時使人擊中系統中缺少的前導零。這條規則將重新添加。

下一條規則是去除415前綴。

DDISearchPattern = "^4150?(?<ddi>\d{9})$" 
DDITranslation = "0${ddi}" 
CLISearchPattern = "^0?(?<cli>\d{9})$" 
CLITranslation = "0${cli}" 

但這是我的問題。在最後一個例子(DDI = 1234020.77億)我要追加CLI將DDI結束,所以我想結束了12340207700000001373000001.

我希望能夠做到這一點:

DDISearchPattern = "^12340?(?<ddi?\d{9})$" 
DDITranslation = "12340${ddi}${cli}" 
CLISearchPattern = "^0?(?<cli>\d{9})$" 
CLITranslation = "0${cli}" 

但不幸的是,${cli}捕獲組是正則表達式CLI,而不是DDI正則表達式的一部分。我怎樣才能從另一個正則表達式中加載一個正則表達式來捕獲這些正則表達式,這樣我就可以使用這兩種捕獲方式進行替換了?

我已經找到一種方法來做到這一點,但它的使用正則表達式來替換@'\$\{cli\}'一個非常混亂的方式。我真的想找到更簡單更好的方法。

+0

它是如何「一個字符串」如果你有兩個輸入字符串,兩名翻譯字符串和兩個輸出字符串?我想你已經知道你可以保存結果並使用'String.Format'來構建字符串。唯一可以結合的是正則表達式到'(? def)|(? 456)',但這是毫無意義的。我不認爲我很理解你的問題...... – Kobi 2011-03-02 21:38:06

+0

@Kobi:也許我應該稍微重新說一遍,以使其更清晰。通過單個字符串,我的意思是將來自兩個表達式的捕獲進行組合並且可用於搜索並替換爲另一個「單個」字符串。我的例子只是表明這發生了兩次,因此有兩個結果。 – BG100 2011-03-02 21:43:39

回答

0

編輯
好吧,我明白你想做什麼。假設引擎不會在正則表達式之間保留分組值。

這將需要的是實際上每個表達式的2遍。先通過捕捉第一/第二,第二遍是與保存的關閉冷杉的取代/從通第二值1.

串pattern_a = "(?<first>def)";
串pattern_b = "(?<second>456)";

//運行具有pattern_a匹配上input_a
串res_first = "${first}";

//運行與input_b
串res_second pattern_b匹配= "${second}";

//使用res_first res_second上input_a運行更換pattern_a
//使用res_first res_second運行input_b一個替代pattern_b
等...

如果我理解正確。 。
我還不知道.net。但通常,直到下一個正則表達式的正則表達式結果纔有效,之後的結果現在無效。

但是,如果沒有,那麼你需要一些更獨立的名稱。

string input_a = "abc-def-ghi"; 
string input_b = "123-4567-89"; 

string pattern_a = "^(?<apre>.*)(?<first>def)(?<apost>.*)$"; 
string pattern_b = "^(?<bpre>.*)(?<second>456)(?<bpost>.*)$"; 

string translation_a = "${apre}A=${first}${second}${apost}"; 
string translation_b = "${bpre}B=${second}${first}${bpost}"; 

如果無效,則需要在第一次運行後保存結果。像這樣的事情(警告,我不是在.NET熟悉連環):

string input_a = "abc-def-ghi"; 
string input_b = "123-4567-89"; 

string pattern_a = "^(?<pre>.*)(?<first>def)(?<post>.*)$"; 
string pattern_b = "^(?<pre>.*)(?<second>456)(?<post>.*)$"; 

// Do the regex for input_a 
// Save off the capture vars here.. 

string A_pre = "${pre}"; 
string A_first = "${first}"; 
string A_post = "${post}"; 

// Do the regex for input_b 

string translation_a = A_pre + "A=" + A_first + "${second}"; 
string translation_b = "${pre}B=${second}" + A_first + "${post}"; 
+0

如果我的翻譯字符串是固定的,這將會很好,但這只是我想要做的一個例子,在我的真實應用程序中,所有這些字符串都存儲在數據庫中,並且可以在運行時更改,所以什麼也不是在編譯時已知。 – BG100 2011-03-02 22:27:18

+0

@ BG100,好吧,我看到你的困境。正則表達式和替換(和組名)都在數據庫中的字符串中。如果他們遵循任何一致性,您可能能夠解析出指定的捕獲組。這將使您能夠解析並替換運行時變量以放入翻譯替換。很多工作,但可能是你唯一的選擇。 – sln 2011-03-02 22:54:45

+0

我知道,我可以這樣做,但它不會很整齊。你的例子給了我一些想法,但我會嘗試更多的東西。謝謝。 – BG100 2011-03-02 22:59:03