我正在构建一个程序来简化 discord 机器人的编码。我想添加内联函数,但似乎我的正则表达式选择器并不完美。
我的程序循环遍历每个内联函数并测试它是否存在于字符串中。并用内联函数返回替换内联函数字符串。
例如{ping}被翻译成91,或者{id author}被翻译成消息作者的id。
问题是如果一个内联函数里面有内联函数。我设法每 1 个解决 1 个内联函数,但随着数字的增长,我的正则表达式选择器失败并且匹配了错误的东西。
我想要它匹配什么:
{avatarurl {id {message}}}
^^^^^^^^^^^^^^
甚至可以匹配这个:
{avatarurl {id {message}}}
^^^^^^^^^
这也是:
{avatarurl {id {message}}}
^^^^^^^^^^^^^^^^^^^^^^^^^^
等等。
它只需要从{(函数名)开始并以}结束。
我的正则表达式选择器无法匹配这部分,它只匹配额外的括号。我需要一个完美的正则表达式选择器来匹配 {blabla},但在放入另一个 {blabla} 时仍然有效。
这是没有成功的模式:
new RegExp(`\{${func.name}([^\}]+[^])*\}`)
func.name 是函数名。 我还需要“{funcname”之后和“}”之前的部分。
这是对括号的通用非正则表达式解决方案(支持不平衡输入)。
然后您可以遍历树并搜索您的匹配项。
function parseBrackets (str, start = 0) {
let children = null;
let pos = start;
loop: while (pos < str.length) {
switch (str[pos]) {
case '{':
let child = parseBrackets(str, pos + 1);
if (!children) {
children = [];
}
children.push(child);
if (child.end == str.length) {
break loop;
}
pos = child.end;
break;
case '}':
if (start == 0) {
children = [{
children, start, end: pos, opened: false, closed: true,
contents: str.slice(0, pos)
}];
}
else {
return {
children, start, end: pos, opened: true, closed: true,
contents: str.slice(start, pos)
};
}
}
pos++;
}
return (start == 0)? children: {
children, start, end: str.length, opened: true, closed: false,
contents: str.slice(start)
};
}
console.log(parseBrackets('NOT OPENED {3}2}1} {avatarurl {id {message}}} blah blah blah {1{2{3} NOT CLOSED'));