我目前正在开发一个简单的PHP模板引擎,并希望替换所有
{% include file="anotherTemplate.tpl" %}
包含给定模板的内容。对于此任务,我使用正则表达式。
private $funcSeparatorL = '{%';
private $funcSeparatorR = '%}';
// ...
preg_match('/' . $this->funcSeparatorL . ' include file="(.*)\.(.*)" ' . $this->funcSeparatorR . '/', $this->content)
这很好但很明显只有隔离器和中间内容之间只有一个空格。我希望能够使用多个空格来使整个事物更具抗错性。
但如果我使用.*
来匹配多个字符,整个页面将永远加载并永远不会完成。
preg_match('/' . $this->funcSeparatorL . '.*include file="(.*)\.(.*)".*' . $this->funcSeparatorR . '/', $this->content)
.*
是处理此类任务的正确方法吗?如果是,为什么会导致这样的错误?
答案 0 :(得分:0)
而不是.*
,只需使用\s*
。这只是匹配空格并避免catastrophic backtracking,这是您当前问题的原因。
示例:
preg_match('/' . $this -> funcSeparatorL . '\s*include file="(.*)\.(.*)".*' . $this -> funcSeparatorR . '/', $this -> content);
顺便说一下,你可以通过摆脱所有其他.*
来进一步改善整个正则表达式,或者在可能的情况下使它们变得非贪婪。未经测试的例子:
preg_match('/' . $this -> funcSeparatorL . '\s*include file="([^"]*?)\.([^"]*)".*?' . $this -> funcSeparatorR . '/', $this -> content);
您可以通过将.*?
替换为[^}]*
来进一步改进,但这取决于您是否允许嵌套模板表达式。
经验法则:如果您输入.+
或.*
而没有非贪婪的限定符(?
),则可能性非常高,您做错了。