JavaScript实现str_find字符串匹配函数时indexOf判定错误问题
问题定位
你写的函数出现偶发返回值错误的核心原因,是对String.prototype.indexOf的返回值判断规则用错了:
- 该方法的实际返回逻辑:匹配成功时,返回目标子串在原字符串中首次出现的起始索引;匹配失败时,统一返回
-1。 - 当目标子串出现在原字符串的第0位(也就是子串和原字符串开头完全重合、甚至和原字符串完全一致)时,方法返回值为
0,并非大于0。你现有代码用word.indexOf(目标) > 0作为匹配判定条件,会把所有位置为0的合法匹配全部漏判。
对应你举的测试用例str_find("123456789&", ["", "123456789&"]):
- 循环到数组第一个元素空串时,
"123456789&".indexOf("")返回0,不满足>0的判断,不会触发匹配标记置真 - 循环到数组第二个元素
"123456789&"时,因为两个字符串完全相等,indexOf同样返回0,还是不满足判断条件
最终函数会错误返回false——这就是你遇到的偶发异常的来源:只要检索到的目标内容在原字符串的索引0位置,就会被误判为不匹配。
除此之外代码还有个小的边界隐患:如果传入的原字符串、待匹配内容不是标准字符串类型(比如传入数字、null值),直接调用indexOf会触发类型报错,也会导致偶发的执行异常。
修正方案
把匹配判断的条件从indexOf(目标) > 0调整为indexOf(目标) !== -1,也就是只要返回值不是代表未匹配的-1,就判定为检索命中。同时增加入参的类型兼容处理,修正后的代码如下:
function str_find(word, find){ // 统一将入参转成字符串,避免非字符串类型调用indexOf报错 const sourceStr = String(word ?? ""); if(!Array.isArray(find)){ return sourceStr.indexOf(String(find ?? "")) !== -1; } else { let matchFlag = false; for (let i = 0, len = find.length; i < len; i++) { if (sourceStr.indexOf(String(find[i] ?? "")) !== -1) { matchFlag = true; break; } } return matchFlag; } }
如果业务规则里不希望将空字符串判定为有效匹配目标,可以在匹配判断处增加过滤,跳过空串的判断分支:
// 仅当待匹配内容不是空串、且能在原字符串中找到时才标记命中 if(find[i] !== "" && sourceStr.indexOf(find[i]) !== -1)
修正后再测试原来的用例,函数会正确返回true,不会再漏判索引0位置的匹配内容。
内容的提问来源于stack exchange,提问作者uu88
相关产品推荐
相关产品推荐

