问题描述
在不同的函数上下文中,let match = Array.from(user_message.matchAll(pattern));
返回不同的结果 - 尽管应用于相同的数据:一次它作为切面工作,另一次它返回一个空数组。
在一个类似 eliza 的聊天机器人中,我有一系列与可能的答案相关联的模式:
this.corpus = [ [/(my name is|I am) (.*)/gi,["%2? such a nice name!",]],];
我正在 let user_message = "My name is Jack";
它适用于上下文 1:
old_answer(user_message) {
let match = null;
let i = 0;
while ((match === null || match.length === 0) && i < this.corpus.length) {
match = Array.from(user_message.matchAll(this.corpus[i][0]));
console.log("Match in old function:",match);
i++;
}
// Do stuff with the match
}
此日志:Match in old function: (1) […] 0: Array(3) [ "My name is Jack","My name is","Jack" ]
同样在上下文 2 中不起作用:
find_all_matches(user_message) {
let matches = new Array();
let match = null;
for (let i = 0; i < this.corpus.length; i++) {
if (this.corpus[i][0].test(user_message)) {
match = Array.from(user_message.matchAll(this.corpus[i][0]));
console.log("Match in new function:",match);
// push match to matches
}
}
return matches;
}
new_answer(user_message) {
let matches = this.find_all_matches(user_message);
if (matches.length === 0) {
return null;
} else {
// Do stuff with the match
}
}
此日志:Match in new function: Array []
我在这里遗漏了什么?
解决方法
那么,我终于找到了问题所在,这是MDN's 字中的问题,
当正则表达式设置了全局标志时,test() 将推进正则表达式的 lastIndex。 (RegExp.prototype.exec() 也提升了 lastIndex 属性。)
进一步调用 test(str) 将继续从 lastIndex 开始搜索 str。每次 test() 返回 true 时,lastIndex 属性都会继续增加。
**注意:只要 test() 返回 true,lastIndex 就不会重置——即使在测试不同的字符串时!
当 test() 返回 false 时,调用正则表达式的 lastIndex 属性将重置为 0.**
find_all_matches(user_message) {
...
for (let i = 0; i < this.corpus.length; i++) {
...
if (regex.test(user_message)) {
// You need to reset the index of the regex after testing the string before you use the regex again
regex.lastIndex = 0;
...
}
}
}