2013-08-20 26 views
1

我有一個Regex.Replace Method (String, String, MatchEvaluator)documentation),我使用的地方MatchEvaluator必須做一些相當繁重的工作。正在對另一個庫使用StandardInputStandardOutput重定向進行調用。庫的性質是這樣的,我必須打開一個StandardInput,然後通過StandardOutput關閉它以獲取我想要的數據。不用說這是一個相當密集的過程。正則表達式MatchEvaluator並行

但是,我的系統上有更多的線程,並想知道是否有辦法讓Regex以並行方式運行。我似乎無法找到任何允許的超載,我似乎也無法概念化Regex的性質。我曾經想過人爲破壞字符串,但是我擔心會導致在正則表達式處理中發生改變的地方出現中斷,因爲它會使用一些環視(儘管不是很多)。

任何人都可以闡明我如何能夠並行化這一點?它是一個包含多個(數百個)匹配項的單個非常大的文檔,需要替換。結果是一個文檔,所有匹配的字符串都被MatchEvaluator函數的輸出所替代。

樣品文件:

Random characters from all over the alphabet that have no use to me in this context. Including =, &, ", ', &, etc. [StringToReplace] More stuff I can ignore. [OtherStringToReplace]. More characters including foreign languages. 

我使用以下Regex

resultText = Regex.Replace(text, "(?<=\])[^\[\]]+(?=\[)", matchEval) 
+0

你可以用圓括號包裝整個模式並使用'Split'。捕獲的結果將在結果數組中返回(在拆分部分之間)。然後,您可以通過簡單的計數來識別匹配的零件,並且假設我並行處理這些零件。 –

+0

你的實際模式在這裏很有幫助,看它是否可以適應這樣的解決方案。 –

+0

但是,我將如何重新加入結果集? (爲什麼不把你的解決方案作爲答案發布,所以我們可以在那裏討論?) – cjbarth

回答

3

假設我想話從此輸入,做一個代價高昂的操作對他們每個人喜歡轉換爲大寫:)

string input = @"abc 123 def 456 ghi 789 jkl mno pqr"; 
string pattern = @"[a-z]+"; 

我會做的是:

1-獲取所有匹配

var matches = Regex.Matches(input,pattern).Cast<Match>().Select(m=>m.Value); 

2 - 請在所有比賽昂貴的操作(平行),結果存儲在一個字典

var dict = new ConcurrentDictionary<string, string>(); 
Parallel.ForEach(matches, m => 
{ 
    Thread.Sleep(1000); // <--Time consuming OP. 
    dict[m] = m.ToUpper(); 
}); 

3-使用詞典進行替換

var output = Regex.Replace(input, pattern, m => dict[m.Value]); 
+0

+1首先檢查字典[m]以避免代價高昂的操作。用生產者消費模式也許可以避免第二次。替換。 OP沒有響應,所以我不傾向於測試。 – Paparazzi

+1

因爲在給定的應用程序運行中,替換計算不會改變,所以使用ConcurrentDictionary確實可以加速很多事情。這是一個非常容易實施的模式。謝謝! – cjbarth