JavaScript 正则表达式有奇怪的行为
JavaScript regular expression having a weird behaviour
我目前正在为我正在维护的 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}'
。
现在让我们开始描述行为,第一次迭代进行得很顺利:函数模块被导入,它被处理并且最终内容被替换为字符串。
问题涉及 second 一个(和所有其他),函数表达式 returns null
的 exec
方法。我根本不明白这一点,首先我认为这是我的 RegExp 的一种错误,也许 {random:1|100}
不匹配但不匹配,因为它在 Regexr.com 上完美运行......最奇怪的是:如果我评估了它 (/\{(.*?):(.*?)\}/g.exec('{range:1|100}
),它不是 return null
,而是我期望的实际结果。
我想我在某个地方错了,但经过几个小时后我仍然不明白为什么它不工作。
我希望你能帮助我,谢谢!
如果您需要任何补充信息,我就在这里。
问题是您正在定义正则表达式 GLOBAL
- 但不要在循环内重置内部指针:
myRegex.lastIndex = 0;
(参见MDN)
- 或者,您可以在 forEach 中重新创建一个正则表达式。
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);
我差点忘了:我建议使用更强大的正则表达式模式:\{(\[^}\]*):(\[^}\]*)\}
不过,你的模式似乎还不错。
我目前正在为我正在维护的 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}'
。
现在让我们开始描述行为,第一次迭代进行得很顺利:函数模块被导入,它被处理并且最终内容被替换为字符串。
问题涉及 second 一个(和所有其他),函数表达式 returns null
的 exec
方法。我根本不明白这一点,首先我认为这是我的 RegExp 的一种错误,也许 {random:1|100}
不匹配但不匹配,因为它在 Regexr.com 上完美运行......最奇怪的是:如果我评估了它 (/\{(.*?):(.*?)\}/g.exec('{range:1|100}
),它不是 return null
,而是我期望的实际结果。
我想我在某个地方错了,但经过几个小时后我仍然不明白为什么它不工作。 我希望你能帮助我,谢谢! 如果您需要任何补充信息,我就在这里。
问题是您正在定义正则表达式 GLOBAL
- 但不要在循环内重置内部指针:
myRegex.lastIndex = 0;
(参见MDN) - 或者,您可以在 forEach 中重新创建一个正则表达式。
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);
我差点忘了:我建议使用更强大的正则表达式模式:\{(\[^}\]*):(\[^}\]*)\}
不过,你的模式似乎还不错。