0

我希望改进以下正则表达式,因为我现在也想匹配嵌套标签:

'%{if:\s*"\'([^\']*)\' == \'([^\']*)\'"}((?:(?!{else}|{/endif}).)*){else}((?:(?!{/endif}).)*){/endif}%sei'

基本上匹配:

{if: "'x' == 'y'"}
    a
{else}
    b
{/endif}

或者

{if: "'x' == 'y'"}
    c
{/endif}

但是,我希望它以某种方式递归,因此嵌套语句也可以在不破坏任何内容的情况下匹配(此时如果添加嵌套语句,它会中断)。

也会有类似的表达!=

我发现这个http://www.devnetwork.net/viewtopic.php?f=38&t=102670&sid=02b7c691a2be894336c694700f8f911a#p551340匹配<div>标签,虽然有点不确定如何调整它以适应我的正则表达式......

4

2 回答 2

0

如果您将嵌套限制在某个预定的深度(这可能是一个坏主意,也可能不是一个坏主意),您可以将其与正则表达式匹配。否则,你不能。您提供的链接将 HTML 与正则表达式相匹配,这通常被使用,但通常认为是一个坏主意。如果您不想使用其他形式的解析,请考虑匹配最里面的 ifs,替换为某物并再次匹配。

于 2012-05-22T12:10:48.673 回答
0

在这种情况下,使用正则表达式 (PCRE) 并不是最佳选择,因为您需要重新解析每个嵌套级别的内部内容(使用适当解析器的原因之一会更好)。

也就是说,可以使用以下模式来完成:

~
{if:\s*+
    (?<condition>
        [^{}]++
    )
}

(?<then>
    (?:
        (?:(?!{if:[^{}]++}|{else}|{/endif}).)*+
        (?R)*+
    )*+
)

(?:
    {else}
    (?<else>
        (?:
            (?:(?!{if:[^{}]++}|{else}|{/endif}).)*+
            (?R)*+
        )*+
    )
)?+

{/endif}
~six

Perl 示例@ideone

在这个文本上

if: "'x' == 'y'"}
    a
{else}
    b
{/endif}

{if: "'x' == 'y'"}
    c
{/endif}

{if:minimal}{else}{/endif}

{if: "'nested' == 'things'"}
    {if: "'x' == 'y'"}x{if:minimal}{else}{/endif}x{/endif}
{else}
    b{if: "'x' == 'y'"}c{/endif}{if: "'x' == 'y'"}c{/endif}
{/endif}

{if:foo} unbalanced {if:bar}ignores first if{/endif}

它匹配

*** matched if:
  * cond: "'x' == 'y'"
  * then:
    a

  * else:
    b

*** matched if:
  * cond: "'x' == 'y'"
  * then:
    c

*** matched if:
  * cond: minimal
  * then:
  * else:
*** matched if:
  * cond: "'nested' == 'things'"
  * then:
    {if: "'x' == 'y'"}x{if:minimal}{else}{/endif}x{/endif}

  * else:
    b{if: "'x' == 'y'"}c{/endif}{if: "'x' == 'y'"}c{/endif}

*** matched if:
  * cond: bar
  * then: ignores first if
于 2012-05-22T12:31:26.837 回答