JavaScript正则表达式具有奇怪的行为

时间:2018-03-22 17:42:06

标签: javascript regex behavior

我正在为我正在维护的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 = /\{(.*?):(.*?)\}/gfoundFunctions = ['{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,而是我期望的实际结果。

我想我错了,但在经过几个小时之后,我仍然不明白为什么它不起作用。 我希望你能帮助我,谢谢! 如果您需要任何补充信息,我就在这里。

1 个答案:

答案 0 :(得分:0)

问题是您正在定义正则表达式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);




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