我正在尝试创建一个正则表达式模式,以匹配我正在构建的小应用程序的“虚假”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]
,因为与生成我试图在此步骤中提取的文本的另一个函数冲突。
编辑:一个打击我的想法是让第三个捕获组捕获并推送到列表阵列,但我不确定这是否会在现实中起作用?到目前为止我还没有工作
JavaScript不支持正则表达式中的递归,否则这将是一种潜在的解决方案。
然而,我会寻求一个不同的解决方案:
您可以依赖DOMParser
- 在浏览器中可用,或者如果您在Node上,可以在几个模块中使用类似的功能。
要使用它,你需要有一个XML格式的字符串,所以除非你想使用<p>
样式的标签,你首先必须将你的字符串转换为该字符串,确保使用<
的内容需要获得<
。
此外,{img}
标签需要得到一个结束标记而不是括号。因此,对于该特定情况需要替换。
一旦完成,就可以直接从该XML获取DOM,这可能已经足够您使用了,但是可以通过简单的递归函数将其简化为您想要的结构:
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
元素也表示为{ li: "...." }
对象。