使用正则表达式删除 RTF 模板中占位符的父段落

Using regular expression to remove the parent paragraph of a placeholder in an RTF template

我正在为我的项目开发合同模块。 合同模板存储为 RTF 模板,其中包含许多占位符,语法为 @placeholder_name@。 每个活动条目在任何给定时间都与特定合同模板相关联。 当活动合同为 requested/downloaded:

  1. RTF 模板作为变量读取。
  2. 文件变量中的占位符替换为活动查询对象的值。
  3. 然后使用 cfcontent.
  4. 将变量发送到浏览器进行下载

问题

如果特定占位符的值为空,我需要删除 rtf 文件中的整个部分。例如:此处的附加信息部分:

我能够在文件中找到以下 rtf 块,这是上面附加信息的整个部分,包括 rtf table 样式。

\par \ltrrow}\trowd \irow0\irowband0\lastrow \ltrrow\ts78\trgaph108\trleft-
810\trbrdrt\brdrdot\brdrw10 \trbrdrl\brdrdot\brdrw10 \trbrdrb\brdrdot\brdrw10 \trbrdrr\brdrdot\brdrw10 \trbrdrh\brdrdot\brdrw10 \trbrdrv\brdrdot\brdrw10     \trftsWidth3\trwWidth11520\trftsWidthB3\trftsWidthA3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid12942116\tbllkhdrrows\tbllkhdrcols\tbllknocolband\tblind-702\tblindtype3 \clvertalt\clbrdrt\brdrdot\brdrw10 \clbrdrl \brdrdot\brdrw10 \clbrdrb\brdrdot\brdrw10 \clbrdrr\brdrdot\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3510\clshdrawnil \cellx2700\clvertalt\clbrdrt\brdrdot\brdrw10 \clbrdrl\brdrdot\brdrw10 \clbrdrb\brdrdot\brdrw10 \clbrdrr\brdrdot\brdrw10 
\cltxlrtb\clftsWidth3\clwWidth8010\clshdrawnil \cellx10710\pard \ltrpar\ql \li0\ri0\sa200\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\pararsid4544034 {\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid3568873 Additional Information}{
\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid4544034 \cell }\pard \ltrpar\ql \li0\ri0\sa200\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid3568873\charrsid4544034 @additional_contract_info@}{
\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid4544034 \cell }\pard \ltrpar\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid4544034 \trowd \irow0\irowband0\lastrow \ltrrow
\ts78\trgaph108\trleft-810\trbrdrt\brdrdot\brdrw10 \trbrdrl\brdrdot\brdrw10 \trbrdrb\brdrdot\brdrw10 \trbrdrr\brdrdot\brdrw10 \trbrdrh\brdrdot\brdrw10 \trbrdrv\brdrdot\brdrw10 
\trftsWidth3\trwWidth11520\trftsWidthB3\trftsWidthA3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid12942116\tbllkhdrrows\tbllkhdrcols\tbllknocolband\tblind-702\tblindtype3 \clvertalt\clbrdrt\brdrdot\brdrw10 \clbrdrl
\brdrdot\brdrw10 \clbrdrb\brdrdot\brdrw10 \clbrdrr\brdrdot\brdrw10 \cltxlrtb\clftsWidth3\clwWidth3510\clshdrawnil \cellx2700\clvertalt\clbrdrt\brdrdot\brdrw10 \clbrdrl\brdrdot\brdrw10 \clbrdrb\brdrdot\brdrw10 \clbrdrr\brdrdot\brdrw10 
\cltxlrtb\clftsWidth3\clwWidth8010\clshdrawnil \cellx10710\row }\pard \ltrpar\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af1 \ltrch\fcs0 \insrsid4544034 
\par }

几天来我一直在努力寻找解决方案。我需要的是 ColdFusion 中的正则表达式语句,以找到包裹在占位符 @additional_contract_info@ 周围的 \par 控制字块,即只有占位符的父段:

the portion: "\par ...@additional_contract_info@ ...." until the ending \par

假设参数没有嵌套。

我不是很精通正则表达式,我尝试用谷歌搜索和搜索 SO 来寻找所有类型的相关问题,但无法解决。我需要帮助!

尝试:

\par\b((?!\par\b).)*@additional_contract_info@.*?\par\b
  • \b 匹配单词边界所以你不匹配 \pard.
  • (?!\par\b). 将首先进行否定前瞻,以确保在比赛开始和 @ 之间没有其他 \par 的实例,然后将消耗单个特点。重复此操作将匹配最近的 \par@.
  • 之间的整个字符串
  • 在最后的 @ 之后你可以使用非贪婪的通配符匹配 .*? (所以它只会匹配最少的字符数)来找到结束段落代码。

示例:

<cfscript>
  str = '\par \par \pard text \par \pard text @additional_contract_info@ text \pard \par text \pard \par } \par }';
  output = REReplace( str, '\par\b((?!\par\b).)*@additional_contract_info@.*?\par\b', '' );
  WriteOutput( output );
</cfscript>

应该输出:

\par \par \pard text  text \pard \par } \par }

更新:

你也可以尝试不使用正则表达式:

<cfscript>
  str      = '\par \par \pard text \par \pard text @additional_contract_info@ text \pard \par text \pard \par } \par }';
  pos      = find( '@additional_contract_info@', str );
  endPos   = find( '\par ', str, pos ) + 4;
  startPos = left( str, pos ).lastIndexOf( '\par ' );
  output   = left( str, startPos ) & right( str, len( str ) - endPos + 1 );
  WriteOutput( output );
</cfscript>

(注意:这假设您总是会找到尾随 space 的 \par,而正则表达式查找单词边界,如果不是这种情况,那么您可能需要尝试其他方法找到要删除的文本的边界)。