Регулярное выражение Javascript для разделения строки с содержимым публикации WordPress в массив (вырезать по коротким кодам)

#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; }