替换RTF文件/模板中的宏

时间:2013-11-04 16:22:37

标签: c# rtf

我正在做一个公平的(至少我假设的)操作。 我有一个包含宏的RTF文件。

我写了一个c#console应用程序,其中我使用了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);

然而,这会失去大量的格式化(颜色,表格,换行等,甚至一些相关的宏):(

替代方法是直接在rtb.Rtf上使用替换但是在没有RichTextbox的情况下直接替换文件本身时问题是相同的:RTF不必保存文本不间断,即(无法找到示例,可能无效:宏\ 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编辑器中看到)所以直接简单的字符串替换在这里不起作用

解决方案

所以我之前发布的解决方案使用regexp替换,没有解决... 但最终它仍然是regexp,但不是在RTF中搜索一个混合宏,而是反过来做了:

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

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

这将返回应该/可能是宏的所有内容

通常会返回类似这样的内容:

  

%} {\ rtlch \ fcs1 \ 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%

所以我使用下面的正则表达式来解决它:

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

之后,我检查并从我从DB中选择的每个宏进行“桥接测试”(不确定使用哪个更好的词)

所以如果我在rtf中有这个字符串:

  

%} {\ rtlch \ fcs1 \ 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%

sanitezed等于:

  

%MACROSET.MACRO%

我有一个KeyValuePair,如:

  

%MACROSET.MACRO%= SomeValue

我做了一些魔法并获得了KeyValuepairs字典,如:

  

%} {\ rtlch \ fcs1 \ 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

然后我替换那些。 如果我没有来自数据库的Macro KeyValuePAir,它将被忽略并滑雪。

将保持更新,因为这是多么成功。

1 个答案:

答案 0 :(得分:0)

RTF格式是纯文本格式。无需在RichTextBox中加载它:您应该能够将其加载到例如StringBuilder,然后搜索并替换您的标签。只是不要忘记逃避您要插入的值:{}\应该变为\{\}和{{1}任何代码为> = 128的字符都应该成为\\,其中####是十进制UTF-16代码单元号。

或者,如果您想要更可靠的解决方案(例如,当我的方法失败时的一个用例 - 如果格式在单个宏键中发生变化),您可以this 3-rd party component