如果你开始使用包含html,text和WordPress短代码的Javascript字符串,例如:
<p>some random<br /> text goes here</p> <p>[foo params=”blue”]</p> <p>random text in html</p> <p>[bar params=”baz”]this has inner content[/bar]</p> <p>last bit of random text<br /> [foobar]this also has inner content [nestedbox params=”zoo”]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
如何调整当前正则表达式以输出所需的数组?
答案 0 :(得分:0)
由于需要获得嵌套数组结构,因此无法仅使用正则表达式执行此操作。即使不需要,正则表达式的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=”blue”]</p> <p>random text in html</p> <p>[bar params=”baz”]this has inner content[/bar]</p> <p>last bit of random text<br /> [foobar]this also has inner content [nestedbox params=”zoo”]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; }