1

我有以下代码:

$text = "Lorem ipsum dolor sit amet, [b]consectetur adipiscing elit[/b]. 
Nunc lorem velit, lacinia ut commodo in, suscipit vitae magna. 
Nam imperdiet neque blandit semper tempus. 
Curabitur sapien ante, vestibulum vitae ante a, condimentum dignissim tortor. Aenean adipiscing tincidunt lorem, non eleifend tellus suscipit a. Nulla convallis [b]
pulvinar ligula[/b], at tempor ante. Fusce a tellus enim. Vivamus nibh eros, ultrices at auctor quis, fringilla nec dolor. Aenean nec tincidunt odio, id pulvinar felis. Pellentesque in augue volutpat, gravida nibh eu, lobortis augue.";

preg_match_all("#(\[b\].*\[/b\])#s", $text, $value);

$value正在从第一个 [b] 返回到最后一个 [/b]。我需要它来单独匹配每一对。

据我了解,我必须s在最后使用 来选择多行,但是*太贪心了。我不能只使用 a?因为我的字符数可能会有所不同......我错过了什么?

4

2 回答 2

2

这是一个常见的错误。除非您采取措施避免它,否则正则表达式引擎将找到可能与您的模式匹配的最长子字符串。根据上下文,可能有各种可能的解决方案,但对于支持 Perl 正则表达式语法的引擎,最简单的通常是使用您正在使用的重复运算符的“非贪婪”变体。即,*?代替*+?代替+??代替?{m,n}?代替{m,n}

因此,在您的示例中,该模式应为:

preg_match_all("#(\[b\].*?\[/b\])#s", $text, $value);
于 2013-10-23T20:11:38.817 回答
1

避免惰性量词的另一种方法:

preg_match_all('~\[b](?>[^[]++|\[(?!/b]))*+\[/b]~', $text, $value);

通过这种方式,您可以避免两个问题:

  1. 贪心量词不是问题,因为字符类在每个左方括号处停止
  2. 因为你不使用点,所以你不关心's'修饰符和换行符。
于 2013-10-23T20:23:19.250 回答