使用 JavaScript 在字符串中获取 'begin' 和 'end' 个块
Getting 'begin' and 'end' of blocks in a string using JavaScript
我正在尝试创建一个函数来获取类似于 code block、return 相应字符索引的字符串部分的开头和结尾。
示例:
abc [ //A0 - start
def [ //B1 - start
ghi [ //C2 - start
jkl
] //D2 - end
] //E1 - end
] //F0 - end
然后 getBlock 函数将接收其中一个字符(“[”或“]”)的字符串和索引以及 return 其对应的索引合作伙伴:
var str = "abc [def [ghi [jkl]]]";
getBlock(str, 4); // returns 20 ("F0" in the example)
getBlock(str, 9); // returns 19 ("E1")
getBlock(str, 14); // returns 18 ("D2")
getBlock(str, 20); // returns 4 ("A0")
getBlock(str, 19); // returns 9 ("B1")
getBlock(str, 18); // returns 14 ("C2")
这是我迄今为止的功能尝试:
function getBlock(str) {
console.log({
"start": Array.from(str.matchAll(/\[/g)).map(m => m.index),
"end": Array.from(str.matchAll(/\]/g)).map(m => m.index)
})
}
getBlock("abc [def [ghi [jkl]]]")
它return是两个数组,包含所有开始和结束字符的索引,但我仍然无法找出单独获取其合作伙伴的逻辑,知道这是否可能吗?
好吧,我最终创建了一个有点丑陋的解决方案,但它似乎按预期工作:
function getBlock(str, i) {
var blocks = Array.from(str.matchAll(/\[|]/g)).map(m => m.index);
return blocks[(blocks.length-blocks.indexOf(i))-1];
}
// must return 20 19 18 4 9 14
var str = "abc [def [ghi [jkl]]]";
console.log(
getBlock(str, 4),
getBlock(str, 9),
getBlock(str, 14),
getBlock(str, 20),
getBlock(str, 19),
getBlock(str, 18)
);
逻辑很简单,不是返回两个数组而是 returns 只返回一个:
[4, 9, 14, 18, 19, 20]
从那里你只需要从“中间”获取值:
14 18
9 19
4 20
就是这样。
编辑:
它适用于每个块内部只有一个块的情况,但如果有两个并排的块则不会。
失败示例:
var str = "abc [def] [ghi]";
getBlock(str, 10) // returns 8 instead of 14
编辑 2(解决方案):
好的,这应该是正确的 JavaScript 解决方案,灵感来自@HereticMonkey 关于 How do I find the position of matching parentheses or braces in a given piece of text? 的评论,唯一的区别是这个版本在 JavaScript 中,并略微更改为允许开始和结束索引。
function getBlock(str, start) {
var end = start;
var counter = 1;
while (counter > 0) {
var direction = (symbol) => ((str[start] == symbol) ? 1 : -1);
var char = str[end += direction("[")];
if (char == "[" || char == "]") {
counter += direction(char)
};
}
return {
"start": start,
"end": end
};
}
var str = "abc [def [ijk]] [ghi]";
console.log(
getBlock(str, 4), // {start: 4, end: 14}
getBlock(str, 9), // {start: 9, end: 13}
getBlock(str, 16) // {start: 16, end: 20}
);
我正在尝试创建一个函数来获取类似于 code block、return 相应字符索引的字符串部分的开头和结尾。 示例:
abc [ //A0 - start
def [ //B1 - start
ghi [ //C2 - start
jkl
] //D2 - end
] //E1 - end
] //F0 - end
然后 getBlock 函数将接收其中一个字符(“[”或“]”)的字符串和索引以及 return 其对应的索引合作伙伴:
var str = "abc [def [ghi [jkl]]]";
getBlock(str, 4); // returns 20 ("F0" in the example)
getBlock(str, 9); // returns 19 ("E1")
getBlock(str, 14); // returns 18 ("D2")
getBlock(str, 20); // returns 4 ("A0")
getBlock(str, 19); // returns 9 ("B1")
getBlock(str, 18); // returns 14 ("C2")
这是我迄今为止的功能尝试:
function getBlock(str) {
console.log({
"start": Array.from(str.matchAll(/\[/g)).map(m => m.index),
"end": Array.from(str.matchAll(/\]/g)).map(m => m.index)
})
}
getBlock("abc [def [ghi [jkl]]]")
它return是两个数组,包含所有开始和结束字符的索引,但我仍然无法找出单独获取其合作伙伴的逻辑,知道这是否可能吗?
好吧,我最终创建了一个有点丑陋的解决方案,但它似乎按预期工作:
function getBlock(str, i) {
var blocks = Array.from(str.matchAll(/\[|]/g)).map(m => m.index);
return blocks[(blocks.length-blocks.indexOf(i))-1];
}
// must return 20 19 18 4 9 14
var str = "abc [def [ghi [jkl]]]";
console.log(
getBlock(str, 4),
getBlock(str, 9),
getBlock(str, 14),
getBlock(str, 20),
getBlock(str, 19),
getBlock(str, 18)
);
逻辑很简单,不是返回两个数组而是 returns 只返回一个:
[4, 9, 14, 18, 19, 20]
从那里你只需要从“中间”获取值:
14 18
9 19
4 20
就是这样。
编辑: 它适用于每个块内部只有一个块的情况,但如果有两个并排的块则不会。 失败示例:
var str = "abc [def] [ghi]";
getBlock(str, 10) // returns 8 instead of 14
编辑 2(解决方案):
好的,这应该是正确的 JavaScript 解决方案,灵感来自@HereticMonkey 关于 How do I find the position of matching parentheses or braces in a given piece of text? 的评论,唯一的区别是这个版本在 JavaScript 中,并略微更改为允许开始和结束索引。
function getBlock(str, start) {
var end = start;
var counter = 1;
while (counter > 0) {
var direction = (symbol) => ((str[start] == symbol) ? 1 : -1);
var char = str[end += direction("[")];
if (char == "[" || char == "]") {
counter += direction(char)
};
}
return {
"start": start,
"end": end
};
}
var str = "abc [def [ijk]] [ghi]";
console.log(
getBlock(str, 4), // {start: 4, end: 14}
getBlock(str, 9), // {start: 9, end: 13}
getBlock(str, 16) // {start: 16, end: 20}
);