js 字符串包含(手把手讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在 JavaScript 开发中,字符串操作是基础且高频的需求之一。无论是验证用户输入、解析 API 响应,还是处理文件内容,开发者时常需要判断一个字符串是否包含特定子字符串。这种需求看似简单,但实现方式却多种多样,不同方法在性能、灵活性、可读性方面各有特点。本文将系统性地讲解 JavaScript 中“字符串包含”的核心知识点,通过对比方法差异、提供实战案例,并结合常见误区分析,帮助读者构建清晰的认知体系。
基础方法:从简单到复杂
1. includes()
:最直观的判断方式
includes()
方法是 ES6 引入的新特性,其语法简洁易懂,直接返回布尔值:
const text = "Hello, JavaScript Developer!";
console.log(text.includes("JavaScript")); // true
console.log(text.includes("Typescript")); // false
形象比喻:可以将字符串视为一个书架,每个字符是书本,includes()
相当于问“这排书架上是否有名为《JavaScript》的书?”——直接给出“有”或“无”的答案。
2. indexOf()
:定位子字符串的位置
若需要同时获取是否存在及位置信息,可使用 indexOf()
:
const index = text.indexOf("Developer");
console.log(index); // 16(从0开始计数)
// 若未找到,返回 -1
关键特性:
- 支持从指定位置开始搜索,例如
text.indexOf("a", 5)
- 对大小写敏感,如
text.indexOf("javascript")
返回 -1
3. search()
与正则表达式
当需要模式匹配时(如模糊查询),可结合正则表达式使用 search()
方法:
const regex = /developer/i; // i 标志表示忽略大小写
console.log(text.search(regex)); // 16(匹配到 "Developer")
此方法返回首个匹配的索引,若无则返回 -1。
4. match()
与 matchAll()
若需获取所有匹配结果,可使用 match()
或 matchAll()
:
const sentence = "apple, apple, and more apple";
const matches = sentence.match(/apple/g); // ["apple", "apple", "apple"]
for (const match of sentence.matchAll(/apple/g)) {
console.log(match.index); // 输出每个匹配的起始位置
}
进阶技巧:场景适配与性能优化
1. 大小写不敏感的处理方案
当需要不区分大小写时,可采用以下两种策略:
// 方法一:强制转为统一大小写
const lowerText = text.toLowerCase();
console.log(lowerText.includes("javascript")); // true
// 方法二:使用正则表达式忽略大小写
console.log(text.search(/javascript/i) !== -1); // true
2. 多条件组合判断
若需同时满足多个包含条件,可将判断逻辑封装为函数:
function isContentValid(text) {
return (
text.includes("privacy") &&
text.includes("terms") &&
text.length > 100
);
}
3. 性能对比与选择建议
方法 | 特点 | 适用场景 |
---|---|---|
includes() | 代码简洁,可读性强 | 基础包含判断 |
indexOf() | 支持位置定位 | 需要获取位置信息时 |
正则方法 | 灵活支持模式匹配 | 复杂模式(如通配符、边界匹配) |
性能测试示例:
// 测试 100万次循环耗时
const largeText = "a".repeat(1e6);
console.time("includes");
for (let i = 0; i < 1e6; i++) {
largeText.includes("a");
}
console.timeEnd("includes"); // 约 100ms
实测表明,includes()
在大多数场景下性能优于 indexOf()
,但具体需结合数据量评估。
常见误区与解决方案
1. 忽略边界条件
// 误区:未考虑空字符串或特殊字符
function checkSubstring(str, substr) {
return str.includes(substr); // 若 str 为 null/undefined 会报错
}
// 改进方案:
function safeCheck(str, substr) {
return str && typeof str === "string" && str.includes(substr);
}
2. 正则表达式元字符未转义
若子字符串包含正则特殊字符(如 .
、*
),需使用 escape()
或手动转义:
const specialChar = "user@domain.com";
// 错误写法:直接使用正则
console.log(/@domain.com/.test(specialChar)); // true(但实际需要精确匹配)
// 正确写法:转义特殊字符
const escaped = specialChar.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
console.log(new RegExp(escaped).test(specialChar)); // true
3. 混淆 ==
与 ===
// 误区:使用 == 导致意外结果
console.log(text.indexOf("abc") == -1); // 正确判断
console.log(text.indexOf("abc") === -1); // 同样正确,但类型严格匹配更安全
实战案例:构建敏感词过滤器
假设需要开发一个简单的敏感词过滤功能,可结合上述方法实现:
const sensitiveWords = ["bad", "error", "fail"];
function filterContent(inputText) {
return sensitiveWords.some(word =>
inputText.toLowerCase().includes(word.toLowerCase())
);
}
// 使用示例
console.log(filterContent("This is a test")); // false
console.log(filterContent("The system failed")); // true
扩展思路:
- 结合
replace()
实现模糊替换:const filtered = inputText.replace( new RegExp(sensitiveWords.join("|"), "gi"), "[filtered]" );
结论
JavaScript 字符串包含的判断是一个看似基础,实则需要深入理解的领域。本文通过对比 includes()
、indexOf()
、正则表达式等方法,结合性能测试、误区分析和实战案例,帮助开发者选择最适合的方案。在实际开发中,建议优先使用 includes()
处理简单场景,而复杂需求(如动态匹配、大小写不敏感)则借助正则表达式实现。通过不断实践与优化,开发者能更高效地解决字符串处理的挑战。
提示:掌握这些方法后,可进一步探索字符串的拆分(
split()
)、替换(replace()
)等操作,构建更强大的文本处理能力。