2

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

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

Rtf 模型具有由应用程序值替换的标签。在大多数 RTF 中,标签没有被分割,因此搜索和替换工作完美。我希望通过少量修改来处理单词。

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

在 2003 年的单词中:

{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 FooBuzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]}

他们的话(word 2007)也分裂了 Foo{garbage inside} Buzz。

所以我希望能够完美地处理常见的 RTF,并检测标签,即使它们被分割了。

我有2个限制。首先没有回归,其次它必须保持简单。性能在这里不是问题。

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

$regExpression = '/\[\[([^\[\]]*)\]\]/';  

preg_match_all($regExpression, $sTemplate, $outKeys); 

更新 :

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

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

生产 :

[0] => Array
    (
        [0] => \rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[
        [1] => \rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 FooBuzz
        [2] => \rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]
    )

更新 2:

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

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

更难的是,我必须能够通过我必须做的任何事情来捕获我的所有示例数据(但不是纯文本)。

对于我的替换正则表达式,它替换了我的标签和所有垃圾。我几乎成功了:

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

但是太贪心了。我想匹配组 { [[}{tag}{ ]]} 并且它匹配 {plain text}{ [[}{tag}{ ]]}{plain text}

我添加 ? 因为我读过它会使 .* 不贪婪,但它不起作用。有任何想法吗 ?

我不明白这个正则表达式有什么问题(标签查找的名称):

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

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

更新 3:

对不起,我不清楚。

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

其次,我必须完全替换 [[FooBuzz]]。所以我必须抓住 {[[}{FooBuzz}}{]]} 仅此而已。

实际上我正在捕捉{我不能捕捉的纯文本} {[[}{FooBuzz}}{]]}}。看我在这里也必须抓到。我正在捕捉:纯文本我不能捕捉 [[FooBuzz]]。

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

{\toto toto}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 FooBuzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]}{\toto toto}
4

2 回答 2

1

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

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

并匹配第一组。

它找到一个前面没有\使用否定lookbehind的整个单词(?<!\\)也告诉它需要在它前面[[和后面]]

是一个示例,您可以看到第一组正确包含FooBar:)

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

编辑:

您的最后一个正则表达式是错误的,因为它期望\w+在最后一个方括号之后正好有一个,它只会匹配类似[[wordWithoutSpaces]].

第一个“update 1”正则表达式正确匹配整个字符串,你说:“从第一个开始{,找到所有东西”。让我们来看看:

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

但是如果要匹配单个部分,则需要创建不同的匹配项或不同的组

编辑

因为只有一个正则表达式可以合并两个正则表达式,所以这个答案是:

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

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

然后由于 strtr 功能,只有与翻译匹配的标签被替换。(工作流程中的 3 轮)。

于 2012-10-12T10:37:34.597 回答
0

以防有些人遇到同样的问题。更好的全球解决方案。文字的 RTF 表示取决于……警察。因此,在 time new roman 中对 [[FooBuzz]] 进行简单的文本搜索即可。但是在 Arial 中,这个词是爆炸式的,你需要一个聪明的正则表达式。

例子 :

Police                Text                                RTF
 Times new roman        [[FooBuzz]]                       {\someRtfTags [[FooBuzz]]}
  Arial                 [[FooBuzz]]                         {\hich\af1\dbch\af12\loch\f1 [[Signature}{\rtlch\fcs1 \af0 \ltrch\fcs0 \i\insrsid15225063 \hich\af1\dbch\af12\loch\f1 President}{\rtlch\fcs1 \af0 \ltrch\fcs0 \i\insrsid1974114\charrsid1974114 \hich\af1\dbch\af12\loch\f1 ]]}

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

于 2012-11-13T11:16:48.870 回答