0

我有一个在 rtf 中处理文档工作流的系统。它适用于标准 Rtf。而且我知道正则表达式能够在 word 2003 中处理它。我希望能够处理 word 2007。

我的标签看起来像这样:[[FooBuzz]]。

许多程序,如写字板,将 [[FooBuzz]] 保留为纯文本。Word 2003 会从标签中分解 [[。Word 2007 更糟糕的是,他在每个大写字母上也爆炸了。所以Foo Buzz。

我的样本数据:

{ toto}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Foo}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Buzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]} {toto}

我需要两件事。首先正则表达式匹配 [[FooBuzz]] 的 rtf 表示

例如: {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Foo}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Buzz}{\ rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]}

其次,我想选择标签的名称。这里是 FooBuzz。我必须使用 php 函数 preg_match_all。

所以这是我的测试数据加倍的测试结果:

Array

( [0] => 数组 ( [0] => {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Foo}{\rtlch\fcs1 \ af0 \ltrch\fcs0 \insrsid2708730 Buzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]} [1] => {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\ fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Foo}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Buzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]})

[1] => Array
    (
        [0] => {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Foo}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Buzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]}
        [1] => {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 [[}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Foo}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2708730 Buzz}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5517131 ]]}
    )

[2] => Array
    (
        [0] => 
        [1] => 
    )

[3] => Array
    (
        [0] => Foo
        [1] => Foo
    )

)

如您所见,它会根据需要生成选项卡。关键 1 是我稍后会处理的错误。键 2 作为结果,仅当 [[FooBuzz]] 未分解时。键 3,作为使用 word 2003 的结果。

所以 Foo 和 Buzz 可能在不同的数组中,这对我来说已经足够了,只要它是一致的。

例子 :

[3] => Array
    (
        [0] => Foo

    )
 [4] => Array
    (
        [0] => Buzz

    ) 

或者

[3] => Array
    (
        [0] => FooBuzz

    )

被接受的答案。

我的正则表达式和他的解释:

我收到了有关 stackoverflow 的帮助来构建它:

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

以更有意义的方式:

/(        Begenning of the OR clause
 \[\[([^\[\]]*?)\]\]   Regex used to catch [FooBuzz] in plain text.
 |   Or statement.
 {[^{]*?\[\[.*?(?<=\[\[).+?  Part able to catch  the Rtf translation of [[
   \b(?<!\\)(\w+)\b     This part have a negative look behind. It match rtf metadata (ex \toto123. And i selects Foo
 (?=.+?\]\]).*?\]\].*?} Match the RTF translations of ]]
 )/ End of or statement.

注意:有很多非贪婪字符(?),这样正则表达式在需要时只选择标签和他的元数据。(以纯文本替换)。

这是遗留代码,我不能决定放弃纯文本方式。性能无关紧要,它是分批运行的。

您将如何捕捉 FooBuzz ?

测试站点:

http://www.spaweditor.com/scripts/regex/index.php显示 preg_match_all 的输出。

http://rubular.com/r/5fm7afU5vG 使用更有趣,您可以编辑永久链接。如您所见,匹配项的显示方式与我的目标函数相同。

简而言之 :

I want to match all the RTF reprsentation of [[FooBuzz]] with match 1.
I want either match x => FooBuzz or match x => Foo match x + 1 => Buzz, if consistent.

您可以随意添加另一个 Or。否则我认为要编辑的部分是: \b(?

4

1 回答 1

1

使用正则表达式模式

/{[^{]*\[{2}.*?\b(\w+)}.*?(?:\b(\w+)}.*?)?\]{2}[^}]*}/
                   ↑             ↑
                  Foo          Buzz

PHP代码:

$pattern = '/{[^{]*\[{2}.*?\b(\w+)}.*?(?:\b(\w+)}.*?)?\]{2}[^}]*}/';
preg_match($pattern, $subject, $matches);

在此处测试此代码。

于 2012-10-15T12:24:09.560 回答