【问题标题】:Regular expression for templating captures too much模板的正则表达式捕获太多
【发布时间】:2012-05-04 05:07:50
【问题描述】:

使用 PHP,我试图让我的正则表达式匹配下面的两个模板引用。问题是,它还从第一个文本块中获取</ul>。当我删除它只捕获第二个引用的/s 标志时。我做错了什么?

/{{\%USERS}}(.*)?{{\%\/USERS}}/s 

这是我的字符串。

<ul class="users">
{{%USERS}}
<li>{%}</li>
{{%/USERS}}
</ul>

{{%USERS}} hello?!{{%/USERS}}

为什么我的表情捕捉太多或太少?

【问题讨论】:

    标签: php regex templates


    【解决方案1】:

    您可能需要使用非贪婪量词。

    *+ 是“贪婪的”。它们会匹配尽可能多的字符。

    *?+? 是“非贪婪的”。它们只会匹配所需数量的字符,以进入正则表达式的下一部分。

    所以在下面的测试字符串中:

    <alpha><bravo>
    
    • &lt;.+&gt; 将捕获 &lt;alpha&gt;&lt;bravo&gt;(因为 . 匹配 &gt;&lt; 为 好吧!)。
    • &lt;.+?&gt; 将捕获 &lt;alpha&gt;

    【讨论】:

      【解决方案2】:

      为什么我的表情捕捉太多或太少?

      1. 它的捕获太多了,因为量词默认是贪婪的(见 Li-aung Yip 回答 +1)

      2. 1234563之间的换行符。

      查看非贪婪的答案

      {{\%USERS}}(.*?){{\%\/USERS}}
      

      here on Regexr,一个测试正则表达式的好地方。

      顺便说一句。我在捕获组之后删除了?,它不需要它,因为* 也匹配空字符串,因此无需另外使其成为可选。

      【讨论】:

      • 我不知道正则表达式默认是贪婪的,很高兴知道!我可以发誓我试过了,但没有用,但我认为这是因为我没有包含 dotall 标志。
      【解决方案3】:

      这是你的正则表达式:

      /{{%USERS}}([^{]+({%[^{]+)?){{%/USERS}}/g
      

      【讨论】:

      • It works,但您应该真正解释一下为什么它有效。 (对于{{%USERS}} {asdf} {{%/USERS}}{{%USERS}}{{%/USERS}} 也会中断。)
      • 由于作者提供的字符串,我创建了正则表达式。没有关于字符串内容的 cmets
      • 当然,但作为称职的程序员,始终有责任进行防御性编码。 ;)
      • php中没有g修饰符,它使用preg_match获取第一个匹配项,preg_match_all获取所有匹配项。
      • 我尝试了很多不同的组合并接近,但它们并没有捕捉到介于两者之间的所有内容,这就是上述组合的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 2020-01-02
      相关资源
      最近更新 更多