我正在寻求改进以下正则表达式,因为我现在也希望匹配嵌套代码:
'%{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>
标签,但有点不确定如何调整它以适应我的正则表达式...
答案 0 :(得分:0)
如果将嵌套限制在某个预定深度(这可能是也可能不是一个坏主意),您可以将它与正则表达式匹配。否则,你不能。您提供的链接将HTML与正则表达式匹配,这通常是使用的,但known通常是个坏主意。如果您不想使用其他形式的解析,请考虑匹配最内层的ifs,替换为某些内容并再次匹配。
答案 1 :(得分: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