我尝试将所有文本添加到注释标记的下一个匹配项以及注释标记的括号之间的文本。 目前我只得到括号之间的注释标记文本而不是下一个注释的内容,它只返回一个空字符串“” 我有点困惑。谢谢!
header("Content-Type:text/plain");
$tmp= file_get_contents("filter.html");
preg_match_all('@<!--\[(.*?)\]-->(.*?)@su', $tmp, $found, PREG_SET_ORDER);
var_dump($found);
filter.html
<!--[%TEST%]-->
TEST
TEST
<!--[%DAS%]-->
DAS TEST
123456
<!--[%BKK%]-->
ABCDEFG
YXZ
我得到的输出是:
array(3) {
[0]=>
array(3) {
[0]=>
string(15) "<!--[%TEST%]-->"
[1]=>
string(6) "%TEST%"
[2]=>
string(0) ""
}
[1]=>
array(3) {
[0]=>
string(14) "<!--[%DAS%]-->"
[1]=>
string(5) "%DAS%"
[2]=>
string(0) ""
}
[2]=>
array(3) {
[0]=>
string(14) "<!--[%BKK%]-->"
[1]=>
string(5) "%BKK%"
[2]=>
string(0) ""
}
}
答案 0 :(得分:1)
解决方案:将正则表达式更改为...
@<!--\[(.*?)\]-->(.*?)(?=<!--|$)@su
说明:原始正则表达式几乎正确地使用了.*?
表达式来获取所有非注释部分。我说'正确',因为这里确实需要懒惰修饰符(否则.*
组合将很乐意消耗整个字符串)。我说'差不多',因为在这种特殊情况下修饰符太懒了 - 即使是空字符串也足以满足它(因为''
匹配/.*/
)。这就是为什么你在$found
中得到那些空字符串的原因 - 懒惰的受害者被带到极端,他们是......
所以我们需要的是让正则表达式的这一部分更加“渴望” - 说服它继续吞噬字符串直到它......
这就是这种前瞻模式所表达的:
(?=<!--|$)
它显示为'仅匹配在新注释之后的位置,或者实际上是字符串的结尾'。这就是它如何将这个懒惰的.*?
子表达式转变成一个有用的运动 - 它不再能够在任何地方想要停止。