【问题标题】:Regex Pattern with two equal but unknown parts具有两个相等但未知部分的正则表达式模式
【发布时间】:2021-11-08 20:09:39
【问题描述】:

我目前正在开发一个简单的模板引擎。在模板中,可以使用 if 语句。 if 块看起来像这样

{% name IF: a EQUALS b %}

content

{% name ENDIF %}

我想通过正则表达式识别这些块。 问题是我需要一个包含两个未知但相等部分的正则表达式模式。 这是匹配所有块的模式:

/{% +(.*) +IF: +(.*) +%}([\s\S]*){% +(.*) +ENDIF +%}/gm

为了明确哪个 ENDIF 标记属于哪个 IF,第一个和最后一个捕获组需要相同。 有没有办法做到这一点?

【问题讨论】:

    标签: php regex


    【解决方案1】:

    你可以使用这个正则表达式:

    {%\s+(\S+)\s+IF:.+?%}(?s)(.+?){%\s+\1\s+ENDIF\s+%}
    

    RegEx Demo

    正则表达式详细信息:

    • {%:匹配{%
    • \s+: 匹配 1+ 个空格
    • (\S+):
    • \s+: 匹配 1+ 个空格
    • IF::匹配IF:
    • .+?:匹配任意字符的 1+(非贪心)
    • %}:匹配%}
    • (?s): 启用 DOTALL 模式,以便点匹配换行符
    • (.+?):第一个捕获组匹配 1+ 个任意字符
    • {%:匹配{%
    • \s+: 匹配 1+ 个空格
    • \1:与我们在捕获组#1 中捕获的值匹配相同的值
    • \s+: 匹配 1+ 个空格
    • ENDIF:匹配ENDIF
    • \s+:匹配 1+ 个空格
    • %}:比赛结束%}

    【讨论】:

    • 这与我在回答中给出的文本块不匹配。
    • 谢谢卡里,我已经处理好了。从问题中不清楚IF 条件块中是否允许独立的%
    【解决方案2】:

    您可以匹配以下正则表达式(设置通用g、多行m 和不区分大小写i 标志)。

    {% +([a-z]+) +IF:.*? +%}\r?\n(?:^.*\r?\n)*?{% +\1 +ENDIF +%}$
    

    Demo

    表达式分解如下(或者,将表达式的每个元素的光标悬停在 regex101.com 链接上以获得对其功能的解释)。

    {% +             # match `{%` followed by one or more spaces
    ([a-z]+) +       # match one or more letters followed by one or more spaces
    IF:.*? +%}\r?\n  # match 'IF: followed by zero or more characters, matched
                     # lazily, followed by one or more spaces followed by '%}'
                     # followed by a line terminator (`\r?` to satisfy Windows)
    (?:              # begin non-capture group
      ^              # match beginning of line
      .*\r?\n        # match one or more characters other than newlines followed
                     # by a line terminator
    )*?              # end non-capture group and execute it zero or more times, lazily
    {% +             # match `{%` followed by one or more spaces
    \1 +             # match the content of capture group 1 followed by one or
                     # more spaces
    ENDIF +          # match `ENDIF` followed by one or more spaces
    %}$              # match `{%` at the end of a line
    

    该链接表明,如果文本块是:

    {% Saffi IF: my { % dog } has fleas %}
    
    content
    
    {% Saffi ENDIF %}
    

    它也会匹配。

    【讨论】:

    • 还有跳蚤吗? :-) 您可以将 \r?\n 缩短为 \R 并可能匹配水平空白字符 \h+ 而不仅仅是空格。
    • @The,她没有被感染;她只养了一些作为宠物。感谢您的提示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    相关资源
    最近更新 更多