JavaScript indexOf忽略大小写

31
我正在尝试查找图像源名称中是否包含大小写不敏感的字符串noPic
var noPic = largeSrc.indexOf("nopic");

我应该写:

var noPic = largeSrc.toLowerCase().indexOf("nopic");

但是这个解决方案不起作用...


largeSrc是什么?你确定它是一个字符串吗? - Josh Stodola
1
使用调试器。在 var noPic = ... 行上设置断点,查看 largeSrc 的类型和值。或者您可以在该行之前放置一个 console.log( typeof largeSrc, largeSrc );。但从问题中可以看出,您可能不熟悉浏览器中的交互式 JavaScript 调试器。我强烈建议您熟悉它。例如:Chrome DevTools 教程 - Michael Geary
6个回答

32

你可以使用带有不区分大小写修饰符的正则表达式——尽管这可能没有indexOf()函数快。

var noPic = largeSrc.search(/nopic/i);

8
根据这个网站:http://jsperf.com/regex-vs-tolowercase-then-regex/2,使用正则表达式的方法比使用 toLower() 方法更快。 - Mike McKay
1
如果搜索词来自用户输入,则使用正则表达式方法会变得更慢,请参见我的答案https://dev59.com/KXM_5IYBdhLWcg3wvV9w#19920595。 - ssmith
如果你需要在一个紧密的循环中执行此操作,它就会派上用场。 - simonzack
我很好奇为什么他最初的方法没有起作用。 - Dandy
2
直到Chrome 64版本,正则表达式方法可能还可以自圆其说,但从69版本开始,根据http://jsperf.com/regex-vs-tolowercase-then-regex/2的测试结果,使用`toLowerCase()`方法的速度快了31倍。 - jdunning
ppumkin 不确定那是否是一个假设的50毫秒,但即使如此也会远远少于那个时间。Mike提供的性能链接显示了惊人的差异,但在我的环境中,它是每秒7M次操作与每秒347M次操作之间的巨大差异。从理论上讲,这是一个巨大的性能差异;然而,我同意你的观点:“你的意思是我仍然可以在一秒钟内执行7百万次吗?我想我还好。”特别是如果它是客户端而不是必须扩展到大量连接服务器端。 - Greg Pettit

23

不,没有一种不区分大小写的方式来调用该函数。也许你的第二个示例无法正常工作是因为你缺少对text()函数的调用。

尝试这样做:

var search = "nopic";
var noPic = largeSrc.text().toLowerCase().indexOf(search.toLowerCase());

3
请注意,对于大字符串,indexOf() 可能会很慢,请参阅 https://dev59.com/DXRB5IYBdhLWcg3wXWO2#4579228。 - ssmith

5
请注意,如果搜索字符串来自用户输入,则需要转义特殊的正则表达式字符。
下面是示例:
var search = getUserInput();

/* case-insensitive search takes around 2 times more than simple indexOf() */
var regex = RegExp(search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "i");

var noPic = testString.search(regex);

请查看更新后的jsperf:http://jsperf.com/regex-vs-tolowercase-then-regex/4

注:正则表达式转义来自https://dev59.com/AXA65IYBdhLWcg3w7DT8#3561711


我删去了你所说的转义正则表达式比toLowerCase()慢的部分,因为我相信这是一个正确的解决方案,并且我有数据证实正则表达式搜索实际上比toLowerCase()更高效。 在我的用例中,文本长度为100 MiB,子字符串约为20个字符:仅调用 toLowerCase() 就需要超过1秒的CPU时间,而直接使用正则表达式搜索则在30毫秒内完成,这只是稍微比普通indexOf()长一点点。 - Klesun

4

尝试使用以下方法:

var lowerCaseLargeSrc = largeSrc.toLowerCase();
var noPic = lowerCaseLargeSrc.indexOf("nopic");

在我看来,比正则表达式更好的解决方案。 - Benj Sanders

1

只有当largeSrc已经是字符串时,您的代码才能正常工作。您可能会得到一个HTML元素而不是字符串作为输入。因此,使用jQuery将任何潜在的输入元素解析为其中的文本。例如:

var noPic = largeSrc.text().toLowerCase().indexOf("nopic");

0

使用findIndex怎么样?这样你就可以在回调函数中完成所有的toLowerCase()操作了。这对我很有用:

// Not Supported in IE 6-11
const arr = ['HELLO', 'WORLD'];
const str = 'world';

const index = arr.findIndex(element => {
  return element.toLowerCase() === str.toLowerCase();
});

console.log(index); // ️ 1

if (index !== -1) {
  // ️ string is in the array
}

Credit: https://bobbyhadz.com/blog/javascript-make-array-indexof-case-insensitive


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接