修改正则表达式模式以将嵌套标记捕获到对象数组中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了修改正则表达式模式以将嵌套标记捕获到对象数组中相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个正则表达式模式,以匹配我正在构建的小应用程序的“虚假”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)

Link to JSbin

我已经意识到我需要模式来捕获嵌套组,并将它们放入一个数组 - 所以上面的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>样式的标签,你首先必须将你的字符串转换为该字符串,确保使用<的内容需要获得&lt;

此外,{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, "&lt;")
               .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);

以上是关于修改正则表达式模式以将嵌套标记捕获到对象数组中的主要内容,如果未能解决你的问题,请参考以下文章

用于从 HTML 元素中捕获标记的正则表达式 [重复]

嵌套捕获组如何在正则表达式中编号?

用于捕获嵌套括号中的值的正则表达式

[javascript] 获取正则子表达式里的内容

Perl 中的正则表达式组:如何从正则表达式组中捕获与字符串中出现的未知数量/多个/变量匹配的元素到数组中?

通过正则表达式删除嵌套在多个 html 标记中的特定单词