Как понять вывод соответствия регулярному выражению PHP ниже?

$file = '{include file="{$COMMON_TPL_PATH}common/header_admin.tpl"}
{include file="{$mainPage}"}
{include file="{$COMMON_TPL_PATH}common/footer_admin.tpl"}';
preg_match('/^(\{\})|^(\{\*([\S\s]*?)\*\})|^(<\?(?:php\w+|=|[a-zA-Z]+)?)|^([     ]*[
]+[  ]*)|^(\{strip\})|^(\{\/strip\})|^(\{literal\})|^(\{\s{1,}\/)|^(\{\s{1,})|^(\{\/)|^(\{)|^(([\S\s]*?)(?=([    ]*[
]+[  ]*|\{|<\?)))|^([\S\s]+)/', $file, $matches);
var_dump($matches);

Почему вывод:

array(13) {
  [0]=>
  string(1) "{"
  [1]=>
  string(0) ""
  [2]=>
  string(0) ""
  [3]=>
  string(0) ""
  [4]=>
  string(0) ""
  [5]=>
  string(0) ""
  [6]=>
  string(0) ""
  [7]=>
  string(0) ""
  [8]=>
  string(0) ""
  [9]=>
  string(0) ""
  [10]=>
  string(0) ""
  [11]=>
  string(0) ""
  [12]=>
  string(1) "{"
}

Мне кажется, что ^([\S\s]+) может соответствовать всей строке..


person smarty    schedule 29.12.2010    source источник
comment
Вы правы насчет [\s\S]. См. этот stackoverflow. ком/вопросы/4544636/   -  person codaddict    schedule 29.12.2010


Ответы (1)


Причина в том, что группа 12 (^(\{)) соответствует успешно, и поэтому механизм регулярных выражений останавливается. Он даже не пытается соответствовать группе 16 (^([\S\s]+)).

Если вы поместите группу 16 перед группой 12, то она будет соответствовать всей строке. Однако, поскольку [\s\S] вообще соответствует любому символу (и может быть сокращено до . при использовании модификатора s), ни одна из других групп никогда не будет соответствовать.

В общем, ваше регулярное выражение выглядит довольно странно. Я не удивлюсь, если он содержит несколько ошибок помимо очевидных недостатков, таких как попытка поместить несколько пробелов в один класс символов.

person Tim Pietzcker    schedule 29.12.2010
comment
Кстати, что означает (?= в приведенном выше регулярном выражении? - person smarty; 29.12.2010
comment
(?=...) — положительный прогноз. Он утверждает, что можно сопоставить его содержимое в текущей позиции, фактически не добавляя эти символы к совпадению. Таким образом, foo(?=bar) будет соответствовать foo, только если за ним следует bar. - person Tim Pietzcker; 29.12.2010