我正在寻找为某种文件编写一个小型解析器,我必须完成的事情之一是查找一行是否在另一行内部,并用缩进(空格或制表符)来定义它。
示例:
This is the main line
This is a nested or child line
我试图通过读取该行中的第一个字符位置并将其与前一个字符进行比较来确定这一点,如下所示:
var str = ' hello';
str.indexOf(str.match(/\S|$/).shift());
我确信这不是最好的方法,而且看起来很糟糕,我还有其他问题需要解决,例如检查缩进是否由空格(2 或 4)或制表符制成,或者传递/维护状态上一行(对象)。
此外,行可以无限嵌套,当然,我更多地寻找一种良好且高性能的算法(或想法)或模式,而不是我认为相对容易执行但容易出错的简单检查。我确信使用解析器和编译器的人们已经解决了这个问题。
<小时/>编辑:
str.search(/\S/);
@Oriol 提案看起来好多了
最佳答案
这通常是您编写解析器的目的,而不是纯粹依赖正则表达式。如果嵌套决定了深度,那么您需要解决两件事:1) 找到任意行的深度,2) 对于每行,迭代行和轨迹集,其中前面的行具有较低的深度值。
如果您熟悉 Javascript 中的 RegExp 函数,则第一个是微不足道的:
function getDepth(line) {
// find leading white space
var ws = str.match(/^(\s+)/);
// no leading white space?
if (ws === null) return 0;
// leading white space -> count the white space symbols.
// obviously this goes wrong for mixed spaces and tabs, and that's on you.
return ws[0].split('').length;
}
第二部分就不那么简单了,因此您有多种选择。您可以迭代所有行,并跟踪行号列表,当您深入时插入列表并在返回时从列表中弹出,或者您可以构建一个简单的树结构(这通常要好得多,因为它可以让您使用标准树构建方法更轻松地扩展其功能。
function buildTree(lines, depths) {
if (!depths) {
var depths = lines.map(e => getDepth);
return buildTree(lines, depths);
}
var root = new Node();
for(var pos=0, end=lines.length; pos<end; pos++) {
var line = lines[pos];
var depth = depths[pos];
root.insert(line, depth);
}
}
当然是使用一个简单的 Node
对象
var Node = function(text, depth) {
this.children = [];
this.line = text.replace(/^\s+/,'');
this.depth = depth;
}
Node.prototype = {
insert: function(text, depth) {
// this is where you become responsible: we need to insert
// a new node inside of this one if the depths indicate that
// is what should happen, but you're on the hook for determining
// what you want to have happen if the indentation was weird, like
// a line at depth 12 after a line at depth 2, or vice versa.
}
}
关于javascript - 查找字符串行是否嵌套或者是另一行的子行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34256844/