为什么PHP的preg_quote会转义不必要的字符?

时间:2018-02-08 01:26:09

标签: php regex pcre preg-quote

来自http://php.net/manual/en/function.preg-quote.php

  

preg_quote()接受 str ,并在作为正则表达式语法一部分的每个字符前放置一个反斜杠。如果您有一个需要在某些文本中匹配的运行时字符串,并且该字符串可能包含特殊的正则表达式字符,这将非常有用。

     

特殊正则表达式字符为: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

     

请注意, / 不是特殊的正则表达式字符。

} 是不必要的,但我可以理解他们为什么要将它包含在对称性中。例如。以下代码有效:

$re = '/}{This is fine}{/';
preg_match($re, $re, $match);
var_dump($match);

输出结果为:

array(1) {
  [0] =>
  string(16) "}{This is fine}{"
}

为什么他们包含 = ! < > : ?据我所知,他们只是在被另一个未转义的元字符引入后才变得特别,例如:在(?之后,两个字符也会被转义。 :也可以是特殊的内部字符类,如:[[:alpha:]],但所有四个括号都会被转义。

2 个答案:

答案 0 :(得分:2)

我认为背后的想法是保持一致的行为。

preg_quote的目标是为正则表达式模式生成文字字符串。这意味着无论上下文如何,返回的字符串中的任何字符都不能被解释为其他内容,并且上下文可以与模式的其他部分串联。

如果我写'/(?' . preg_quote('>') . 'abc)/',我希望>不会被解释为原子组的>,并且该模式会返回错误。

如果我写'/.{3' . preg_quote('}') . '/',我希望}不会被解释为量词的结束括号,并且模式匹配像'a{3}'这样的字符串,但不是'abc'

您可以使用先行断言,命名组,非捕获组或原子组轻松地为= ! < > :构建相同类型的示例。

重要的是,无论使用函数的方式或上下文,预期的行为总是相同的。

答案 1 :(得分:0)

如果您尝试编写如下代码,会发生什么:

$lookahead = getUserInput();  // Not escaped
$results = preg_match('/abc(?' . $lookahead . ')/', $subject);

用户输入!def?答案是你得到负面的预测而不是常规的前瞻。如果您不想允许否定前瞻,那么您将需要确保转义感叹号。