#javascript #regex
#javascript #регулярное выражение
Вопрос:
Если вы начинаете со строки Javascript, которая содержит html, текст и короткие коды WordPress, подобные этому примеру:
<p>some random<br /> text goes here</p> <p>[foo params=amp;#8221;blueamp;#8221;]</p> <p>random text in html</p> <p>[bar params=amp;#8221;bazamp;#8221;]this has inner content[/bar]</p> <p>last bit of random text<br /> [foobar]this also has inner content [nestedbox params=amp;#8221;zooamp;#8221;]this nest has inner content[/nestedbox][/foobar]</p>
Возможно ли иметь регулярное выражение для изменения строки на следующую:
array[
'<p>some random<br /> text goes here</p><p>',
'[foo params="blue"]',
'</p> <p>random text in html</p><p>',
array[
'[bar params="baz"]',
'this has inner content',
'[/bar]'
],
'</p> <p>last bit of random text<br />'
array[
'[foobar]',
'this also has inner content',
array[
'[nestedbox params="zoo"]',
'this nest has inner content',
'[/nestedbox ]'
],
'[/foobar]'
]
];
Короче говоря, регулярное выражение должно разделяться только по коротким кодам внутри строки, и в зависимости от того, является ли короткий код самозакрывающимся ( [foo ...]
) или открытым / закрытым ( [foobar....]...[/foobar]
), его нужно разделить рекурсивно, как показано выше.
После некоторого экспериментирования на https://regex101.com , Мне удалось разделить только различные основные части (хотя и не совсем) с этим, и я немного застрял:
/(.*?)[(.*?)]/g
Как можно настроить мое текущее регулярное выражение для вывода нужного массива?
Комментарии:
1. Обязательно ли это должно быть на JS? Анализатор коротких кодов в WordPress не использует regex, он также сопоставляет совпадения с зарегистрированными короткими кодами из плагинов. Взгляните на
strip_shortcodes()
в коде .
Ответ №1:
Сделать это исключительно с помощью регулярных выражений невозможно, из-за структуры вложенного массива, которую вам нужно получить. И даже если бы это не было необходимо, у регулярных выражений JavaScript недостаточно возможностей для сопоставления вложенных пар открывающих и закрывающих тегов.
Поэтому я бы предложил использовать для этого фрагмент кода JavaScript. Возможно, потребуется немного больше тестирования, поскольку я успешно применил его только к вашим образцам данных:
function nest(s) {
var a = s.match(/[/?w.*?]|[^[] /g), i = 0, closed;
return (function recurse(endtag) {
for (var res = [], v; v = a[i]; i ) {
if (v == endtag) {
res.push(v);
return [res]; // return as nested
} else if (v.match(/^[/w.*?]$/)) {
i--;
return res; // return as non-nested
} else if (!v.match(/^[w.*?]$/) || !res.length) {
// normal text or opening tag at start of
// new part
res.push(v);
} else {
// opening tag: recurse
res = res.concat(recurse('[/' v.match(/w /)[0] ']'));
}
}
return res;
})();
}
// Sample data
var s = '<p>some random<br /> text goes here</p> <p>[foo params=amp;#8221;blueamp;#8221;]</p> <p>random text in html</p> <p>[bar params=amp;#8221;bazamp;#8221;]this has inner content[/bar]</p> <p>last bit of random text<br /> [foobar]this also has inner content [nestedbox params=amp;#8221;zooamp;#8221;]this nest has inner content[/nestedbox][/foobar]</p>';
// Call the function
var a = nest(s);
// Show output
console.log(a);
.as-console-wrapper { max-height: 100% !important; top: 0; }