2013-11-04 92 views
0

我正在做一個相當(至少我假設如此)的操作。 我有一個帶有宏的RTF文件。替換RTF文件/模板中的宏

我寫了一個c#控制檯應用程序,其中我使用了System.Windows.Forms.RichTextBox組件。

短版:

RichTextBox rtb=new RichTextBox(); 
rtb.LoadFile(input,RichTextBoxStreamType.RichText); 
foreach(var macroPair in dictionary) 
{ 
    while (rtb.Find(macroPair.Key) > -1) 
    { 
     rtb.Select(rtb.Find(macroPair.Key), macroPair.Key.Length); 
     rtb.SelectedText = macroPair.Value; 
    } 
} 
rtb.SaveFile(outputRichTextBoxStreamType.RichText); 

然而,這失去了很多格式化(顏色,表,新的生產線等,甚至一些relace宏):(的

的替代方法是使用直接替換在rtb.Rtf上,但在沒有RichTextbox的情況下直接替換文件本身時,問題是一樣的:RTF不必保存文本不中斷,即(無法找到示例,可能無效:Macro \ f252Key。 當您打開RTF它顯示MacroKey好,但我不能得到它拯救的方式:(

感謝任何見解

例子:

這是從一個RTF copypaste:

Contract No: \tab %}{{\*\bkmkstart __DdeLink__5913_841230768}\dbch\af3\rtlch \ltrch\loch\lang1033 
DEFAULT.}{{\*\bkmkend __DdeLink__5913_841230768}\dbch\af3\rtlch \ltrch\loch\lang1033 
CONTRACT_REALID%} 

正如你似乎%默認值。和CONTRACT_REALID%是由RTF格式化出於某種原因分開(什麼我可以在RTF編輯器中看到),所以直接簡單的字符串替換犯規這裏工作

解決方案

因此,解決辦法我前面貼使用正則表達式替換,沒有工作...... 但最終它仍然是正則表達式,但不是搜索RTF內的混凝土宏我反其道而行之:

首先我匹配RTF中的所有宏使用以下RegEx:

string sideregexp = @"[\{\}\\a-zA-Z0-9_*:\s ]+"; 
MatchCollection mc = Regex.Matches(input, "%" + sideregexp + @"\." + sideregexp + "%", RegexOptions.Singleline); 

這將返回我的一切,應該/可能是宏

通常它返回是這樣的:

%} {\ rtlch \ FCS,\ AF1 \ ltrch \ fcs0 \ FS20 \ insrsid13847909 \ HICH \ AF1 \ DBCH \ af31505 \湖\ F1 MACROSET.MACRO} {\ rtlch \ FCS1 \ AF1 \ ltrch \ fcs0 \ FS20 \ lang1036 \ langfe1033 \ langnp1036 \ insrsid13847909 \ HICH \ AF1 \ DBCH \ af31505 \ loch \ f1%

所以我sanitaze使用它的如下因素正則表達式:

Regex.Replace(Regex.Replace(mc[index].Value, @"([\\}{]|(__))+[a-zA-Z_\\*0-9\n}{\r]+[ \n\r]", ""), "[\n\r ]", "") 

之後,我檢查和我從數據庫中選擇的每個宏我做了一個「橋測試」(不知道有什麼更好的詞來使用)

所以,如果我有這個字符串中的RTF:

%} {\ rtlch \ FCS,\ AF1 \ ltrch \ fcs0 \ FS20 \ insrsid13847909 \ HICH \ AF1 \ DBCH \ af31505 \湖\ F1 MACROSET。MACRO} {\ rtlch \ FCS1 \ AF1 \ ltrch \ fcs0 \ FS20 \ lang1036 \ langfe1033 \ langnp1036 \ insrsid13847909 \ HICH \ AF1 \ DBCH \ af31505 \湖\ F1%

其中sanitezed等於:

%MACROSET.MACRO%

和我有像KeyValuePair:

%MACROSET.MAC RO%= someValue中

我做一些魔術和得到像KeyValuepairs的解釋:

%} {\ rtlch \ FCS,\ AF1 \ ltrch \ fcs0 \ FS20 \ insrsid13847909 \ HICH \ AF1 \ dbch \ af31505 \ loch \ f1 MACROSET.MACRO} {\ rtlch \ fcs1 \ af1 \ ltrch \ fcs0 \ fs20 \ lang1036 \ langfe1033 \ langnp1036 \ insrsid13847909 \ hich \ af1 \ dbch \ af31505 \ loch \ f1%= SomeValue

然後我代替那些。 如果我沒有從數據庫的宏KeyValuePAir它被忽略和滑雪。

將不斷更新,如何成功的,這是。

+0

的RTF代碼的一個例子是有益的 – Jerry

+0

這是從RTF一個copypaste: 合同號:\標籤%} {{\ * \ bkmkstart __DdeLink__5913_841230768} \ DBCH \ AF3 \ rtlch \ ltrch \湖\ lang1033 DEFAULT。} {{\ * \ bkmkend __DdeLink__5913_841230768} \ DBCH \ AF3 \ rtlch \ ltrch \湖\ lang1033 CONTRACT_REALID%} 正如你似乎%默認值。和CONTRACT_REALID%是由某種原因RTF格式化(什麼我可以在RTF編輯器中看到),所以直接簡單的字符串替換不工作分開這裏 –

+0

這些書籤,這就是爲什麼你不能看到他們。如果你不需要它們,你可以用正則表達式去除它們。另一個問題:你想如何修改後的rtf看起來像? – Jerry

回答

0

RTF格式是純文本爲主。無需將其加載到RichTextBox中:您應該能夠將其加載到StringBuilder,然後搜索並替換您的標籤。只是不要忘記逃避你插入值:{}\應該成爲\{\},並且\\,並與代碼任意字符> = 128應該成爲\u####?其中####是十進制的UTF-16碼單位編號。或者,如果您想要更可靠的解決方案(例如,當我的方法將失敗 - 如果格式在一個宏密鑰內更改),您可以使用您的this 3-rd party component

+0

這是一個很好的解決方案,解決問題RTF能夠混合文本和格式化數據,即:這是一些{rtf formatin}文本 –