今天我们来聊聊一个非常基础,但又天天都会用到的JavaScript问题:怎么判断一个字符串里,包不包含另一个字符(或字符串)?
这篇文章,我们就来把这些方法一个一个掰开揉碎,讲清楚。
方法一览
JavaScript里,主要有这几个方法来检查字符串包含:
| | | | |
|---|
includes() | | | 区分 | 最常用、最直观 |
indexOf() | | | | |
search() | | | | |
match() | | | | |
test() | | | | |
下面,我们一个个来看。
1. includes() 方法:简单直接的答案
这是你现在最应该首先考虑的方法。 它的目的非常单纯:告诉我“有”还是“没有”。
基本用法
let str = "Hello, world!";
let result = str.includes("world");
console.log(result); // 输出:true
就这么简单。如果字符串 str 里包含了子串 "world",它就返回 true,否则返回 false。
它区分大小写
let str = "Hello, world!";
console.log(str.includes("World")); // 输出:false
因为 "World" 开头的 W 是大写,而原字符串里是 "world",小写 w。所以没找到,返回 false。
可以指定开始搜索的位置
includes() 方法还可以接受第二个参数,表示从字符串的哪个位置开始找。
let str = "JavaScript is fun!";
console.log(str.includes("is", 5)); // 从索引5开始找,输出:true
console.log(str.includes("is", 12)); // 从索引12开始找,输出:false
优点:
缺点:
- • 只是ES6(2015年)才加入的新方法,在非常古老的浏览器(比如IE)里不支持。不过现在基本不用考虑这个问题了。
2. indexOf() 方法:经典而强大
在 includes() 出现之前,indexOf() 是完成这个任务的主力军。它更“老”,但功能也更底层一些。
基本用法
let str = "Hello, world!";
let position = str.indexOf("world");
console.log(position); // 输出:7
indexOf() 返回的是子串第一次出现的位置(索引)。索引从0开始计数。"world" 在 "Hello, world!" 中,从第7个字符(w)开始。
关键点:如果没找到,它会返回 -1。
所以,我们通过检查返回值是否不等于 -1,来判断是否包含。
let str = "Hello, world!";
if (str.indexOf("world") !== -1) {
console.log("找到了!");
} else {
console.log("没找到。");
}
// 输出:找到了!
它也区分大小写,也能指定起始位置
let str = "abcABCabc";
console.log(str.indexOf("ABC")); // 输出:3
console.log(str.indexOf("abc")); // 输出:0
console.log(str.indexOf("xyz")); // 输出:-1 (没找到)
console.log(str.indexOf("abc", 2)); // 从索引2开始找,输出:6
indexOf() vs includes():
- • 如果你只关心“有没有”,用
includes()。代码更简洁:if (str.includes('x'))。 - • 如果你还需要知道“在哪里”,用
indexOf()。因为它返回位置索引。 - • 从性能上看,两者几乎没有差别。选择哪个,主要看你的需求和个人习惯。
3. search() 方法:正则表达式入门
当你需要更灵活的匹配规则时,比如“忽略大小写”,或者匹配一个模式(比如数字、空格),search() 方法就派上用场了。
基本用法
search() 接受一个正则表达式作为参数,返回第一个匹配到的索引,没找到则返回 -1。这点和 indexOf() 很像。
let str = "Hello, WORLD!";
// 使用正则表达式 /world/i, 其中的 i 表示忽略大小写
let position = str.search(/world/i);
console.log(position); // 输出:7
看,即使原字符串是 "WORLD",我们通过正则的 i 标志(ignore case)实现了不区分大小写的查找。
它只能返回第一个匹配的位置
let str = "apples and apples";
console.log(str.search(/apples/)); // 输出:0
它只告诉你第一个 "apples" 在哪,不会管后面还有几个。
注意: search() 的参数如果是一个字符串,它会被隐式地转换成正则表达式。但这可能带来意外,所以最好直接传正则表达式。
// 不推荐:字符串会被转成 /./,匹配任何单个字符
console.log("hello".search(".")); // 输出:0
// 推荐:明确使用正则
console.log("hello".search(/\./)); // 输出:-1 (找真正的点号)
4. match() 方法:提取匹配的内容
match() 比 search() 更进一步。它不只是告诉你位置,还能把匹配到的内容拿出来给你看。
基本用法
let str = "The year is 2023 and next is 2024.";
let result = str.match(/\d+/); // 正则 \d+ 匹配一个或多个数字
console.log(result);
// 输出一个数组: [ '2023', index: 12, input: 'The year is 2023 and next is 2024.', groups: undefined ]
返回的数组里,第一个元素就是匹配到的字符串 "2023"。同时,数组还有 index 属性告诉你位置。
使用 g 标志进行全局搜索
如果正则表达式带了 g(global)标志,match() 会返回所有匹配项组成的数组,但没有 index 等信息了。
let str = "2023 and 2024";
let result = str.match(/\d+/g);
console.log(result); // 输出: [ '2023', '2024' ]
如何用它判断是否包含?
检查 match() 的返回值是不是 null。
let str = "Hello world";
if (str.match(/world/)) {
console.log("包含!");
}
5. 正则表达式的 test() 方法
严格来说,这不是字符串的方法,而是正则表达式对象的方法。但它太常用了,必须提一下。
基本用法
你先创建一个正则表达式,然后用它的 test() 方法来测试字符串。
let str = "Hello, world!";
let regex = /world/;
let result = regex.test(str);
console.log(result); // 输出:true
test() 直接返回布尔值,非常适合用在条件判断里。它通常比 match() 更快,因为你不需要提取匹配内容。
实现复杂检查的例子
// 检查字符串是否至少包含一个数字和一个大写字母
let password = "Pass123";
let hasNumber = /\d/.test(password);
let hasUpper = /[A-Z]/.test(password);
if (hasNumber && hasUpper) {
console.log("密码强度不错!");
}
一些常见的“坑”与注意事项
- 1. 大小写问题:
includes(), indexOf() 默认都区分大小写。如果你需要忽略大小写,要么先把字符串全转成小写(toLowerCase()),要么使用正则方法。// 方法:转成小写统一比较
let str = "JavaScript";
console.log(str.toLowerCase().includes("script")); // true
- 2. 特殊字符与正则:当你用
search()、match() 或 test() 时,参数是正则表达式。如果子串里有 .、*、? 等正则特殊字符,它们会有特殊含义,可能导致搜索错误。这时需要对它们进行“转义”。let filename = "test.js";
// 错误:. 在正则里匹配任意字符
console.log(filename.search(".js")); // 输出:0 (匹配了't')
// 正确:对点进行转义
console.log(filename.search(/\.js/)); // 输出:4
- 3.
indexOf 检查 -1:这是一个经典写法,但很容易把 !== -1 错写成 === -1,逻辑就反了。用 includes() 可以避免这个心智负担。 - 4. 性能考量:对于超长的字符串和极其频繁的操作,
indexOf() 有时可能略快一丁点,因为它是更底层的方法。但在99%的情况下,这种差异可以忽略不计。代码的清晰度和可维护性更重要。
希望这篇文章,能帮你彻底搞清楚在JavaScript里如何判断字符串包含。下次再遇到这个问题,你就可以自信地选出最适合的那个方法了。
该文章在 2026/2/26 16:09:51 编辑过