Regex: неправильный синтаксис, используемый с preg_replace_callback?

Я позаимствовал код из этой ссылки шаблон регулярного выражения PHP - найти все вхождения { {var}} для реализации средства применения значений к файлам шаблонов. Это использует функцию preg_replace_callback()

мой предпочтительный метод именования - это имя1.имя2.имя3=значение, а не имя1_имя2_имя3=значение, но регулярное выражение, которое я использую, похоже, имеет проблему.

Этот не работает.

файл шаблона

.aclass{
  font-width:{{newsflash.font.width}};
}

значения .ini

newsflash.font.width=8px

используется регулярное выражение

'!\{\{(\w+).+\.\w+\}\}!'

вывод print_r($matches)

Array
(
  [0] => {{newsflash.font.width}}
  [1] => newsflash
)

подстановка неверна, поскольку $matches[1] является неверным ключом.

.aclass{
  font-width:;
}

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

Полный код с ошибочным регулярным выражением приведен ниже.

$inputFileName = 'templateVars.css';
$outputFileName = 'templateVals.css';
$varsFileName = 'variables.ini';

$ini_array = parse_ini_file($varsFileName);
$matchesArray = array();

function replace_value($matches) {
  global $ini_array;
  global $matchesArray;
  print "<pre>";
  print_r($matches);
  print "</pre>";
  return $ini_array[$matches[1]];
}


$inputFileVar = file_get_contents($inputFileName);

print "<pre>";
print_r($ini_array);
print "</pre>";


print "<pre>";
print $inputFileVar;
print "</pre>";

$outFileVar = preg_replace_callback('!\{\{(\w+).+\.\w+\}\}!', 'replace_value', $inputFileVar);

print "<pre>";
print $outFileVar;
print "</pre>";

print "<pre>";
print $matchesArray;
print "</pre>";

Шаблон для сопоставления

.aclass{
  font-width:{{newsflash.font.width}};
  color:{{newsflash.font.color}}
}

Содержимое файла .ini

newsflash.font.width=8px
newsflash.font.color=red

person Community    schedule 12.09.2009    source источник
comment
Массив совпадений кажется правильным ... можете ли вы выполнить обратный вызов замены и какой результат вы бы хотели получить?   -  person Lazy Bob    schedule 13.09.2009


Ответы (2)


символ . не является частью \w; и ваш .+ (за пределами скобок группировки) будет соответствовать любой непустой строке (. является подстановочным знаком). Следовательно, $matches[1]=newsflash правильно.

Что вы хотите, чтобы $matches[1] было? Это не ясно из вашего вопроса, извините.

person mihi    schedule 12.09.2009
comment
Я понимаю вашу точку зрения, я хочу, чтобы match[1] был newsflash.font.width, в английском языке это должно быть либо слово без точек, либо последовательность слов с точками в конце, за которой следует слово без точки. - person ; 13.09.2009
comment
в этом случае используйте '!\{\{((?:\w+\.)*\w+)\}\}!' в качестве регулярного выражения, если все слова должны содержать хотя бы одну букву (т. е. они не должны совпадать с some..junk). - person mihi; 13.09.2009
comment
кроме того, вы можете опустить ?:, если вам не важно существование элемента match[2]. - person mihi; 13.09.2009
comment
Ваш пример работал отлично. Каково значение '?:' ? - person ; 13.09.2009
comment
(?:...) аналогичен (...) только тем, что круглые скобки не будут создавать элемент в массиве совпадений (в данном случае matches[2]). () необходимы для того, чтобы * повторял и точку, и слово. - person mihi; 13.09.2009

!\{\{(\w[\.\w]*)\}\};?!

это регулярное выражение, похоже, прекрасно соответствует вашим шаблонам.

person SilentGhost    schedule 12.09.2009