gpt4 book ai didi

javascript - 从数组中配对 HTML 标签

转载 作者:行者123 更新时间:2023-12-02 21:42:50 26 4
gpt4 key购买 nike

从数组中很好地配对单个 HTML 标签的最佳方法是什么?所以我使用正则表达式从字符串中按顺序剪切所有标签并将它们放入数组中,所以如果我有一个像

这样的字符串
"
<div id='one'>
<span>
<h1></h1>
</span>
</div>
<div id='two'>
<a>
<span></span>
</a>
</div>
"

没有c的换行符,然后按照html的顺序匹配到一个数组中,所以["<div id='one'>", "<span>", "<h1>", "</h1>", "</span>", "</div>", "<div id='two'>"]等等,但我一直在努力从数组中以良好的方式将它们配对,所以它会是这样的

{
parentHTML = "<div id='one'></div>",
childrenHTML = "<span><h1></h1></span>",
children: {
parentHTML = "<span></span>",
childrenHTML = "<h1></h1>"
}
}
{
parentHTML = "<div id='two'></div>",
childrenHTML = "<a><span></span></a>",
children: {
parentHTML = "<a></a>",
childrenHTML = "<span></span>"
}
}

我几乎已经为此提出了一个解决方案,尽管它是如此庞大且有缺陷,最终也会引发错误,所以我的意思是我只是想知道这是否可以以某种方式得到简化

 function obj(parent) {
this.parentXML = parent
this.childrenXML = ''
}
var final = []
var string = "<div id='hey'><span><span></span><div></div><div id='bob'></div><div></div></span></div>"
var str = string.match(/<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>/g)
str.forEach(function(i, e) {
if (!i.match(/<\/.+>/)) {
var parent = new obj(i)
var name = i.match(/[a-zA-Z0-9.]+/)
final.push(parent)
var d = e
function recall(t) {
d++
var val = str[d]
if (name[0] == val.match(/[a-zA-Z0-9.]+/)[0] && val.match(/<\/.+>/) && t == true) {
final[e].parentXML += str[d]
console.log(final)
} else {
final[e].childrenXML += str[d]
if (!val.match(/<\/.+>/)) {
recall(false)
} else {
recall(true)
}
console.log(final)
}
}
recall()
} else {
var parent = new obj(i)
}
});
console.log(final)

我的意思是,这可能要求太多,但我将不胜感激任何帮助。 :)

最佳答案

我认为这是一个需要解决的有趣问题,所以这是我的实现。

我将逻辑分离为各种辅助函数,希望使其更具可读性。我添加了对识别自关闭且不能有子元素的 HTML 元素的支持。

const html = `
<div class="header">
<h1>This is my header</h1>
</div>
<div class="body">
<p>This is some text and a <a href="#">link</a>.</p>
</div>
<div class="footer">
<ul>
<li><a href="#">One</a></li>
<li><a href="#">Two</a></li>
<li><a href="#">Three</a></li>
</ul>
</div>
`;

function parseHTMLElements(html) {
return html.match(/(<[^>]+>)/gm);
}

function buildTree(elements) {
const tree = [];

while (elements.length) {
const element = elements.shift();

if (isOpeningElement(element)) {
const childTree = buildTree(elements);
const node = buildNode(element, childTree);
tree.push(node);
}
else if (isSelfClosingElement(element)) {
const node = buildNode(element);
tree.push(node);
}
else if (isClosingElement(element)) {
return tree;
}
}

return tree;
}

function buildNode(element, children = []) {
const parentHTML = getParentHTML(element);
const childrenHTML = getChildrenHTML(children);

return { parentHTML, childrenHTML, children };
}

function isOpeningElement(element) {
return /^<[^/]+>$/.test(element);
}

function isClosingElement(element) {
return /^<\/.+>$/.test(element);
}

function isSelfClosingElement(element) {
return /^<(area|base|br|embed|hr|iframe|img|input|link|meta|param|source|track).*>$/.test(element);
}

function getClosingElement(element) {
return element.replace(/<\/?([^\s\\/>]+).*>/, '</$1>');
}

function insertHTML(elementHTML, innerHTML) {
if (isSelfClosingElement(elementHTML)) {
return elementHTML;
}

return elementHTML.replace(/^(<[^>]+>)(.*)$/, (matches, openingElement, closingElement) => {
return `${openingElement}${innerHTML}${closingElement}`;
});
}

function getParentHTML(openingElement) {
if (isSelfClosingElement(openingElement)) {
return openingElement;
}

const closingElement = getClosingElement(openingElement);
return `${openingElement}${closingElement}`;
}

function getChildrenHTML(children) {
if (children.length === 0) {
return '';
}

return children.reduce((html, child) => {
const childHTML = getChildrenHTML(child.children);

return html + insertHTML(child.parentHTML, childHTML);
}, '');
}

const elements = parseHTMLElements(html);
const tree = buildTree(elements);
console.log(tree);

关于javascript - 从数组中配对 HTML 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60327570/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com