
本文旨在提供一种使用 JavaScript 解析包含嵌套括号的字符串的通用方法,通过构建 BracketTree 类,能够有效地处理不平衡的括号输入,并遍历树结构以查找特定模式的匹配项,无需复杂的正则表达式即可实现精准匹配。
正则表达式在处理嵌套结构时常常显得力不从心,容易出现匹配错误。BracketTree 类提供了一种更可靠的解决方案,它通过将字符串解析成树形结构,从而能够轻松地处理嵌套的括号,即使括号不平衡也能正确解析。
BracketTree 类的构造函数接收两个参数:brackets(包含开始和结束括号的字符串)和 string(需要解析的字符串)。
class BracketTree {
constructor (brackets, string) {
if (typeof brackets != 'string' || brackets.length != 2 || brackets[0] == brackets[1]) {
return null;
}
let opening = brackets[0];
let closing = brackets[1];
// ... 内部解析函数 ...
}
}构造函数首先进行参数校验,确保 brackets 是一个包含两个不同字符的字符串。然后,它定义了内部的 parse 函数,用于递归地解析字符串并构建树形结构。
立即学习“Java免费学习笔记(深入)”;
parse 函数是 BracketTree 的核心,它接收一个起始位置 start 作为参数,并递归地解析字符串,构建一个表示括号结构的树形对象。
function parse (start) {
let children = [];
let pos = start;
loop: while (pos < string.length) {
switch (string[pos]) {
case opening:
let child = parse(pos + 1);
children.push(child);
if (child.end == string.length) {
break loop;
}
pos = child.end;
break;
case closing:
if (start == 0) {
children = [{
children, start, end: pos, opened: false, closed: true,
contents: string.slice(0, pos)
}];
}
else {
return {
children, start, end: pos, opened: true, closed: true,
contents: string.slice(start, pos)
};
}
}
pos++;
}
return (start == 0)? {
children, start, end: string.length, opened: false, closed: false,
contents: string
}: {
children, start, end: string.length, opened: true, closed: false,
contents: string.slice(start)
};
}parse 函数遍历字符串,遇到开始括号时递归调用自身,创建一个子节点并添加到当前节点的 children 数组中。遇到结束括号时,返回一个包含子节点信息的对象。如果括号不平衡,parse 函数会尽力构建尽可能完整的树形结构。
BracketTree 类还提供了一个 traverse 方法,用于遍历构建好的树形结构,并对每个节点执行回调函数。
traverse (callback) {
if (typeof callback != 'function') {
return false;
}
let root = this.root;
let input = root.contents;
let nodeId = 0;
function recurse (parent, level) {
// ... 内部递归函数 ...
}
recurse(root, 0);
return true;
}traverse 方法接收一个回调函数 callback 作为参数,该函数将在每个节点上被调用。traverse 方法使用内部的 recurse 函数进行递归遍历。
以下是一个使用 BracketTree 类的示例:
let input = 'NOT OPENED {3}2}1}***{avatarurl {id {message}}} blah blah blah {1{2{3} NOT CLOSED';
let tree = new BracketTree('{}', input);
function filteredTraverse (caption, leafFilter, branchFilter) {
console.log(`${'-'.repeat(29 - caption.length/2)} ${caption} `.padEnd(60, '-'));
leafFilter ??= () => true;
branchFilter ??= () => true;
tree.traverse((args) => {
if (args.branch) {
return branchFilter(args);
}
if (leafFilter(args)) {
console.log(`${' '.repeat(args.level)}<${args.contents}>`);
}
});
}
filteredTraverse(
'Ignore unbalanced and all their descendants',
null,
({branch}) => branch.opened && branch.closed
);
filteredTraverse(
'Ignore unbalanced but include their descendants',
({parent}) => parent.opened == parent.closed
);
filteredTraverse(
'Ignore empty',
({start, end}) => start != end
);
filteredTraverse(
'Show non-empty first children only',
({childId, start, end}) => childId == 0 && start != end
);这段代码首先创建了一个 BracketTree 对象,然后定义了一个 filteredTraverse 函数,该函数使用 traverse 方法遍历树形结构,并根据提供的过滤器输出特定节点的信息。
BracketTree 类提供了一种强大的方法来解析包含嵌套括号的字符串。与正则表达式相比,它更易于理解和维护,并且能够更好地处理不平衡的括号。通过使用 BracketTree 类,您可以轻松地提取和处理嵌套结构中的信息,从而简化您的 JavaScript 代码。在需要处理复杂嵌套结构的场景下,BracketTree 类是一个值得考虑的替代方案。
以上就是JavaScript 解析嵌套括号:构建 BracketTree 类实现精准匹配的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号