我正在为我正在维护的Discord机器人制作脚本语言,而且我面临着一个奇怪的问题。以下代码将字符串作为输入(I think {if:3|=|0|you are|TechRax is} {range:1|100}
),使用字符串的match
方法从字符串中获取所有函数(表达式:/\{(.*?):(.*?)\}/g
)。然后使用forEach
处理所有这些匹配,然后使用replace
方法将匹配的内容替换为字符串上的结果。
以下是我使用的代码:
let newString = 'I think {if:3|=|0|you are|TechRax is} {range:1|100}';
const functionPattern = /\{(.*?):(.*?)\}/g;
const foundFunctions = newString.match(functionPattern);
if (!foundFunctions) throw new Error('No function found');
foundFunctions.forEach((fn) => {
const parsedInput = functionPattern.exec(fn); // = null once the second iteration begins... ? only the first one work. Same issue if I invert the function orders (first works, second and + no)
if (!parsedInput || !parsedInput[1] || !parsedInput[2]) return;
try {
/*const customFunction = new (require(`../../Production/Tags/${parsedInput[1]}`))(this.client, context, contextType);
if (!customFunction) return;
const result = customFunction.run(parsedInput[2].split('|'));*/
const result = 'Stack Overflow test';
newString = newString.replace(fn, result);
} catch (e) {
newString = newString.replace(fn, e);
}
});
// Print newString here (depends if you're on browser or node)
在此上下文中,this.client.constants.functionPattern = /\{(.*?):(.*?)\}/g
,foundFunctions = ['{if:4|=|0|you are|alien is}', '{range:1|100}']
和newString = 'I think {if:{argslen}|=|0|you are|{args} is} {range:1|100}'
。
现在让我们开始描述行为,第一次迭代顺利进行:函数模块被导入,它被处理,最终内容被替换为字符串。
问题涉及第二一个(以及所有其他问题),函数表达式的exec
方法返回null
。我根本不明白这一点,首先我认为这是我的RegExp的一种错误,也许{random:1|100}
不匹配但不是因为它在Regexr.com上完美运行而且......最怪异的:如果我评估它(/\{(.*?):(.*?)\}/g.exec('{range:1|100}
),它不会返回null
,而是我期望的实际结果。
我想我错了,但在经过几个小时之后,我仍然不明白为什么它不起作用。 我希望你能帮助我,谢谢! 如果您需要任何补充信息,我就在这里。
答案 0 :(得分:0)
问题是您正在定义正则表达式GLOBAL
myRegex.lastIndex = 0;
(请参阅MDN)
let newString = 'I think {if:3|=|0|you are|TechRax is} {range:1|100}';
let functionPattern = /\{([^}]*):([^}]*)\}/g;
const foundFunctions = newString.match(functionPattern);
if (!foundFunctions)
throw new Error('No function found');
foundFunctions.forEach(fn => {
//const functionPattern = /\{([^}]*):([^}]*)\}/g; // or redeclare
const parsedInput = functionPattern.exec(fn);
if (!parsedInput || !parsedInput[1] || !parsedInput[2]) return;
try {
const result = 'Stack Overflow test';
newString = newString.replace(fn, result);
functionPattern.lastIndex = 0; // reset internal pointer of your regex
} catch (e) {
newString = newString.replace(fn, e);
}
});
console.log(newString);

我差点忘了:我建议使用更强大的正则表达式模式:\{(\[^}\]*):(\[^}\]*)\}
但是,你的模式似乎还不错。