【问题标题】:Balanced regular expression平衡正则表达式
【发布时间】:2015-01-16 23:47:15
【问题描述】:

所以我开始使用正则表达式,并尝试使用正则表达式匹配以下文本的 outer {% tag xyz %}{% endtag %} tags

{% tag xyz %}
   {% tag abc %}
   {% endtag %}
{% endtag %}

我的正则表达式如下所示并且到目前为止有效:

({%)\s*(tag)([^%}]*?)(?:\s*(?:(%})((?:(?:[^{%]*?)|(?R))*)(?:({%)\s*(end\2)\s*(%}))))

但是,只要匹配标记内的文本包含单个 {% 符号,正则表达式就不会按预期工作。我认为这是因为字符类可能匹配{%,但也可能匹配{% 作为单个字符。我尝试了很多,最终尝试和错误,但没有成功。

对这个问题有帮助吗?

我为您设置了两个 regex101 链接来显示问题:

非常感谢任何帮助!

【问题讨论】:

  • 这不是标准正则表达式处理的东西(在一般情况下)。如果您有 PCRE(与 Perl 兼容的正则表达式),并且它们足够兼容,那么您也许可以使用支持嵌套表达式的 Perl 功能,但那些“正则表达式”不再是真正的“正则”。您应该提供更多关于您计划在何处使用此代码的上下文。

标签: regex tokenize lexer


【解决方案1】:

尝试将[^{%] 替换为(?:(?!{%).) 并添加s (PCRE_DOTALL) flag

这将允许{ 在其间使用否定的lookahead,而不是%

测试your updated pattern 或这里另一个开始尝试:

/{% tag \w+ %}(?:(?:(?!{%).)|(?0))*{% endtag %}/gs

test at regex101

【讨论】:

  • 谢谢乔尼。我也尝试了前瞻方法,但我用错了。看起来前瞻总是需要一些东西来向前看到;-)我忘记了.,只是尝试了(?:(?!{%))而不是(?:(?!{%).)
  • @techworker 原因是,你想消耗字符/前进。 (?:(?!{%))* 只会量化一个位置(零宽度),它会停止。比如()+停留在同一位置see example。环视不会在字符串中移动,它们会在指定位置朝一个方向看。很高兴它现在可以工作了:)
猜你喜欢
  • 2015-11-04
  • 2019-01-17
  • 2016-12-07
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 2010-10-07
相关资源
最近更新 更多