研究并替换Word Rtf



我正在开发一个应用程序,该应用程序具有用于邮寄邮件的工作流。这些邮件是根据我的应用程序业务规则生成的。

模型是html或Rtf格式的,只要用户不使用word创建Rtf,它就可以完美地工作。这不在规格范围内,但如果不涉及太多工作,我的层次结构将欢迎Word兼容性,这将取悦并缓解我们客户的生活。

Rtf模型具有被应用程序值替换的标记。在大多数RTF中,标签是不拆分的,因此搜索和替换工作非常完美。我希望能做一些修改。

示例数据:[[FooBuzz]]在大多数rtf中没有拆分。

2003年:

{rtlchfcs1 af0 ltrchfcs0 insrsid5517131 [[}{rtlchfcs1 af0 ltrchfcs0 insrsid2708730 FooBuzz}{rtlchfcs1 af0 ltrchfcs0 insrsid5517131 ]]}

他们的话(2007年的话)也分裂了Foo(垃圾内部)Buzz。

因此,我希望能够完美地处理常见的RTF,并检测标签,即使它们是分裂的。

我有两个约束条件。首先不要倒退,其次必须保持简单。性能不是问题。

我使用的是symfony 1.4。实际相关研究代码部分:

$regExpression = '/[[([^[]]*)]]/';  
preg_match_all($regExpression, $sTemplate, $outKeys); 

更新:

我想我主要需要完善这个正则表达式。我正在研究一些正则表达式,但它们仍然需要一些改进:

/([a-zA-Z0-9]+)/  

生产:

[0] => Array
(
[0] => rtlchfcs1 af0 ltrchfcs0 insrsid5517131 [[
[1] => rtlchfcs1 af0 ltrchfcs0 insrsid2708730 FooBuzz
[2] => rtlchfcs1 af0 ltrchfcs0 insrsid5517131 ]]
)

更新2:

我对正则表达式仍然有一些问题。它实际上第一次找到了标记值和纯文本。我不确定在合理的时间内我想要什么是可能的。

我需要修改正则表达式,这样她就可以得到相同的结果,但在[[]]中,实际上它也适用于纯文本。

更困难的是,我必须能够通过任何我必须的方式捕获所有的样本数据(但不是纯文本)

对于我的replace regex,它替换了我的标记和所有垃圾。我几乎成功了:

/{.*?[[.*(?<!\)w+b.*]].*?}/

但它太贪婪了。我想匹配组{[[}{tag}{]]},并且它匹配{纯文本}

我加上?因为我读过它会让**变得不贪婪,但它不起作用。有什么想法吗?

我不知道这个regex(标签查找的名称)有什么问题:

[[(b(?<!\)w+b)]]

根据我的理解。它说,在[[]]内部,找到任何不以反斜杠开头,后跟任何单词字符的单词。我说得对吗?

更新3:

对不起,我说不清楚。

我的第一个正则表达式旨在捕获[[FooBuzz]]中的FooBuzz。第二个是抓[[FooBuzz]]。因此,在第一个正则表达式中,我只想捕获文本FooBuzz,而忽略其他所有内容(如{}\eoeoe)。

其次,我必须完全取代[[FooBuzz]]。所以我必须抓住{[[}{FooBuzz}}{]]},什么都不做。

事实上,我正在捕捉{我可能没有捕捉到的纯文本}{[[{FooBuzz}}{]]}。看,我在这儿也得抓。我正在捕捉:我可能无法捕捉到纯文本[[FooBuzz]]。

对于[[部分,我只需要抓住这个:{\rtlch\fcs1\af0\ltrch\fcs0\insrsid5517131[[}。我想这是因为他找不到不合理的匹配。所以他处于贪婪模式。并且失败了这个数据示例:

{toto toto}{rtlchfcs1 af0 ltrchfcs0 insrsid5517131 [[}{rtlchfcs1 af0 ltrchfcs0 insrsid2708730 FooBuzz}{rtlchfcs1 af0 ltrchfcs0 insrsid5517131 ]]}{toto toto}

编辑后,要查找FooBuzz或任何其他标签,您可以搜索

(?<=[[).+?b(?<!\)(w+)b(?=.+?]])

并匹配第一组。

它使用负查找(?<!\)找到一个不在前面的完整单词,也告诉它需要在[[前面,然后在]]后面

在这里举一个例子,你可以看到第一组正确地包含FooBar:)

为了更好地理解RTF,我找到了一个很好的链接,我认为你也可以考虑非正则表达式的方法,即使在这种情况下我没有任何线索。

编辑:

您的上一个正则表达式是错误的,因为它在最后一个方括号后面正好期望一个w+,它只匹配类似[[wordWithoutSpaces]]的内容。

第一个"update1"正则表达式正确匹配整个字符串,您说:"从第一个{开始,然后查找所有内容"。让我们看看:

  • {.*?[[匹配{[[之间的所有内容
  • .*(?<!\)w+b匹配[[之后和第一个单词字符w之前的所有字符(前面可能没有反斜杠)(这里您可能希望在负查找和w之前有一个b)
  • .*]].*?}/匹配]]和您找到的第一个}之间的所有内容(非贪婪)

但如果你想匹配单个零件,你需要创建不同的匹配或不同的组

编辑

由于只有一个正则表达式可以合并两个正则表达式,因此答案如下:

{[^{]?[[.(?<=[[).+?b(?]].?}

Preg_match_all将返回2个选项卡。1包含正则表达式匹配的数据,第二个包含标记。

然后,由于strtr函数,只有与翻译匹配的标记才会被替换。(工作流中的3轮)。

如果有些人遇到同样的问题。一个更好的全球性解决方案。RTF对单词的表达取决于。。。警察部门因此,对时代新罗马作品中的[[FooBuzz]]进行简单的文本搜索。但在Arial中,这个词是爆炸式的,你需要一个聪明的正则表达式。

示例:

Police                Text                                RTF
Times new roman        [[FooBuzz]]                       {someRtfTags [[FooBuzz]]}
Arial                 [[FooBuzz]]                         {hichaf1dbchaf12lochf1 [[Signature}{rtlchfcs1 af0 ltrchfcs0 iinsrsid15225063 hichaf1dbchaf12lochf1 President}{rtlchfcs1 af0 ltrchfcs0 iinsrsid1974114charrsid1974114 hichaf1dbchaf12lochf1 ]]}

所以使用Times new Roman作为标签。

最新更新