2. 题:解析tpl
const parseHTML = (tpl) => {
let parsedList = []; // {tagName: '', type: 'start' | 'end'}[]
while (tpl.trim()) {
const tagName = tpl.match(/<\/?(\w+)+?/)?.[1];
if (!tagName) {
return parsedList;
}
const oneTag = tpl.match(new RegExp(`(<\/?${tagName}[^>]*)+?`))[0];
const item = {
tagName,
type: 'start'
};
if (oneTag.includes('/')) {
item.type = 'end';
}
parsedList.push(item);
tpl = tpl.replace(oneTag, '');
}
return parsedList;
};
const createAst = list => {
if (!list.length) {
return list;
}
let root = {...list.shift()};
const stack = [root];
for (const {type, tagName} of list) {
const head = stack[stack.length - 1];
if (type === 'start') {
head.children = head.children || [];
const item = {tagName};
head.children.push(item);
stack.push(item);
} else {
stack.pop();
}
}
return root;
};
createAst(parseHTML());