我正在尝试创建正则表达式模式,以匹配我正在构建的小型应用程序的“人造” html标记。
我创建了正则表达式来捕获{tag}brackets{/tag}
中找到的匹配项,并将其输出到这样的对象数组中:
{
{key : value},
{key : value}
}
当前模式的代码:
let str = "{p}This is a paragraph{/p} {img}(path/to/image) {ul}{li}This is a list item{/li}{li}Another list item{/li}{/ul}";
let regex = /\{(\w+)}(?:\()?([^\{\)]+)(?:\{\/1})?/g;
let match;
let matches = [];
while (match = regex.exec(str)) {
matches.push({ [match[1]]: match[2]})
}
console.log(matches)
我已经意识到,我还需要一种模式来捕获嵌套组,并将它们放入数组中-因此上述string
的结果将是:
[
{p : "This is a paragraph"},
{img : "path/to/image"},
{ul : ["This is a list item", "Another List item"]}
]
这里的想法是按顺序匹配每个标签,以便数组的索引与找到它们的顺序匹配(即,上面字符串中的第一段为array[0]
,依此类推)。
如果有人对我如何构建模式有什么投入,将不胜感激。 如果有什么不同,我将不会有超过1层的深层嵌套。
如果可以这样做,我可以灵活地为ul
使用不同的标记,但是由于与生成我要提取的文本的另一个函数冲突,我不能使用方括号[text]
这一步。
编辑:一个让我大吃一惊的想法是让第三个捕获组捕获并推送到列表数组,但是我不确定这在现实中是否可行?到目前为止,我还没有开始工作
答案 0 :(得分:0)
JavaScript不支持正则表达式内的递归,否则这将是一个潜在的解决方案。
但是我会寻求其他解决方案:
您可以依靠DOMParser
-在浏览器中可用,或者,如果您在Node上,则几个模块中都可以使用类似的功能。
要使用它,您需要一个XML格式的字符串,因此,除非要使用<p>
样式的标签,否则首先必须将字符串转换为该字符串,并确保包含{{ 1}}则需要获取<
。
此外,<
标记将需要获得一个结束标记,而不是括号。因此,对于这种特殊情况,必须进行更换。
一旦这种方法不起作用,从该XML中获取DOM就很简单了,它可能已经足够您使用,但是可以通过简单的递归函数将其简化为所需的结构:
{img}
除了const str = "{p}This is a paragraph{/p} {img}(path/to/image) {ul}{li}This is a list item{/li}{li}Another list item{/li}{/ul}";
const xml = str.replace(/\{img\}\((.*?)\)/g, "{img}$1{/img}")
.replace(/</g, "<")
.replace(/\{/g, "<").replace(/\}/g, ">");
const parser = new DOMParser();
const dom = parser.parseFromString("<root>" + xml + "</root>", "application/xml").firstChild;
const parse = dom => dom.nodeType === 3 ? dom.nodeValue.trim() : {
[dom.nodeName]: dom.children.length
? Array.from(dom.childNodes, parse).filter(Boolean)
: dom.firstChild.nodeValue
};
const result = parse(dom).root;
console.log(result);
元素也表示为li
对象之外,输出几乎是您想要的。