Регулярное выражение Javascript для содержимого шаблонов Twig
Я использую Rich Text Editor, чтобы разрешить онлайн модификацию шаблонов Twig. Twig - это шаблонизатор, использующий следующий синтаксис для отображения переменных:
{{ object.property }}
Он также использует функции для генерации URL, такие как:
{{ url('mr_message_read', {id: message.id}) }}
Теперь я хочу отобразить рядом с моим редактором список переменных и функций TWIG, используемых в шаблоне. Для этого я извлекаю текущее содержимое в формате HTML с помощью ключевых слов "twig", как показано выше. Чтобы извлечь ключевые слова, я использую регулярное выражение ниже:
var reg = /{{[^}]+}}/g;
var match = text.match(reg);
console.log( match );
Это будет работать в примере 1, но не в примере 2, так как для функции Twig требуется строка }. Итак, я попробовал несколько других синтаксисов, чтобы разрешить "все, кроме}}". Ни один из них не кажется подходящим
var reg = /{{[^}]+}}/g; // GOOD but ignores second example
var reg = /{{[^}}]+}}/g; // Idem
var reg = /{{[^}}]*}}/g; // Idem
var reg = /{{(^}}+)}}/; // null
var reg = /{{(^}})+}}/; // null
var reg = /\{\{[^\}\}]+\}\}/g; // Ignores second example
var reg = /\{\{[^}}]+\}\}/g; // Ignores second example
var reg = /\{\{[^\}\}]+\}\}/g; // Ignores second example
var reg = /\{\{[^[}}]]+\}\}/g; // Ignores second example
Я борюсь сейчас. Я полагаю, это проблема с побегом, но я застрял:)
Пример содержания:
<p>{{ author.fullname }} wrote you a message. Read it here: <a href="{{ url('mr_message_read', {id: message.id}) }}">Messagerie</a>.</p>
<hr />
<blockquote>
<p>{{ message.content|nl2br }}</p>
</blockquote>
РЕДАКТИРОВАТЬ: мое решение на основе кода Томаса
function getTwigTags(){
var str = CKEDITOR.instances['form_content'].getData();
var regex = /{{\s*([^{]*{([^{]*):\s*(.*?)}.*?|[^{]*)\s*}}/g;
var keywords = new Array();
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
if(match !== 'undefined' && groupIndex == 1)
// console.log(`Found match: group ${groupIndex}: ${match}`);
keywords[keywords.length] = match;
});
}
return keywords;
}
1 ответ
Вы можете использовать этот код:
const regex = /{{\s*([^{]*{([^{]*):\s*(.*?)}.*?|[^{]*)\s*}}/g;
const str = `{{ url('mr_message_read', {id: message.id}) }}
{{ object.property }}`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
if(match !== 'undefined' && groupIndex > 0)
console.log(`Found match: group ${groupIndex}: ${match}`);
});
}