#php #regex #preg-replace #preg-replace-callback
Вопрос:
Я пытаюсь создать «простой» анализатор регулярных выражений, чтобы сгенерировать некоторые шаблоны в своем проекте. Я сделал этот фрагмент регулярного выражения для сопоставления и разбора циклов — что кажется правильным, и я нахожу все, что хочу, и мой цикл заменяет значения.
Последнее, с чем я борюсь, — это избавление от лишних n
символов, которые, похоже, остались после замены внутреннего цикла. Я пробовал добавлять различные n
или s
удалять их захват, но что-то всегда выключено/оставлено.
Как я могу обновить регулярное выражение, чтобы не переносить разрывы строк из группы захвата тела?
s*(?<body>. n*)
довел меня до последнего n
перед заключительной улицей.
Шаблон:
<ul class="row">
<{ foreach( $Users as $user ) }>
<li><{ $user }></li>
<{ endforeach }>
</ul>
Ожидаемый:
<ul class="row">n
<li>Fred</li>n
<li>Chris</li>n
<li>Tor</li>n
</ul>n
Фактический:
<ul class="row">n
n
<li>Fred</li>n
n
<li>Chris</li>n
n
<li>Tor</li>n
n
</ul>n
Регулярное foreeach
выражение для захвата loop
/<{s*foreach(s*$(?<variable>w )s ass $(?<value>w )s*)s*}>(?<body>. )<{s*endforeachs*}>/si
Замена заполнителя
/<{s*$(?<variable>w )?s*}>/i
Когда я выполняю замену, он использует совпадающее имя variable
, чтобы найти некоторые значения, а затем заменяет все, что он находит в теле.
Вот упрощенная версия того, что работает:
$users = ['Users' => 'Fred', 'Jack', 'Chris'];
preg_replace_callback($regex, function (array $matches) use ($variables): string {
$output = '';
foreach (resolveValue($matches, $users) as $value) {
$scope = array_merge(
$this->variables,
[$matches['value'] => $value]
);
$output .= replaceVars($matches['body'], $scope);
}
return $output;
},
$template
);
function replaceVars() {
$regex = '/<{s*$(?<variable>w )?s*}>/i';
return (string) preg_replace_callback($regex,
function (array $matches): string {
return resolveValue($matches);
},
$template
);
}
function resolveValue($matches, $scope) {
$variable = $matches['variable'] ?? null;
if (isset($scope[variable])) {
return $scope[variable];
}
throw Exception();
}
Игровая площадка, показывающая, как работает регулярное
выражение https://regex101.com/r/SAua6n/1
Комментарии:
1. Невозможно пропустить их, сопоставляя строку, содержащую их. Удалите эти разрывы строк после того, как будет найдено совпадение.