0

0

js怎么判断字符串是否包含子串

煙雲

煙雲

发布时间:2025-08-23 14:32:01

|

630人浏览过

|

来源于php中文网

原创

判断字符串是否包含子串最推荐使用includes(),因其语义清晰且直接返回布尔值;2. 若需获取子串位置或兼容旧浏览器,则选用indexof(),通过返回值是否为-1判断存在性;3. 对于复杂模式匹配或不区分大小写的查找,应使用正则表达式,其中test()方法适合布尔判断,match()可返回匹配详情;4. 实现不区分大小写查找时,可统一转换大小写后比较,或更优地使用正则表达式i标志;5. 需注意空字符串始终被视为包含、长字符串高频操作的性能影响、旧浏览器对includes()不支持及复杂unicode字符的处理限制,选择方法时应权衡需求、可读性与性能,最终方案需完整考虑场景并避免常见陷阱。

js怎么判断字符串是否包含子串

在JavaScript中判断一个字符串是否包含另一个子串,我们通常会用到几种内置方法:

String.prototype.includes()
String.prototype.indexOf()
,以及更灵活的正则表达式。选择哪种方法,很大程度上取决于你的具体需求——是仅仅需要一个布尔结果,还是需要子串出现的位置,亦或是更复杂的模式匹配。

解决方案

判断字符串是否包含子串,最直接且现代的方式是使用

includes()
方法。如果需要知道子串首次出现的位置,或者需要兼容旧版浏览器,
indexOf()
则是经典选择。而对于复杂的模式匹配或不区分大小写的查找,正则表达式则提供了强大的能力。

以下是具体的实现方式:

1. 使用

String.prototype.includes()

这是ES6引入的方法,也是我个人最推荐的,因为它语义最清晰,直接返回一个布尔值,表明是否找到了子串。

const mainString = "Hello, world! Welcome to JavaScript.";
const subString1 = "world";
const subString2 = "TypeScript";

console.log(mainString.includes(subString1)); // true
console.log(mainString.includes(subString2)); // false

// 也可以指定开始搜索的位置
console.log(mainString.includes("world", 10)); // false (从索引10开始,"world"在前面)

2. 使用

String.prototype.indexOf()

这是一个历史悠久的方法,如果找到子串,它会返回子串首次出现的索引位置;如果没有找到,则返回

-1
。你可以根据这个返回值来判断。

const mainString = "Hello, world! Welcome to JavaScript.";
const subString1 = "world";
const subString2 = "TypeScript";

console.log(mainString.indexOf(subString1)); // 7 (子串"world"从索引7开始)
console.log(mainString.indexOf(subString2)); // -1

// 判断是否包含
if (mainString.indexOf(subString1) !== -1) {
    console.log("包含子串:", subString1);
}

// 同样可以指定开始搜索的位置
console.log(mainString.indexOf("world", 10)); // -1

3. 使用正则表达式 (

RegExp.prototype.test()
String.prototype.match()
)

正则表达式提供了最强大的模式匹配能力,尤其当你需要进行复杂匹配(如不区分大小写、匹配多种模式等)时,它几乎是唯一的选择。

  • RegExp.prototype.test()
    : 这是最适合判断是否包含的方法,因为它只返回一个布尔值,效率高。

    const mainString = "Hello, world! Welcome to JavaScript.";
    const pattern1 = /world/; // 匹配"world"
    const pattern2 = /TypeScript/; // 匹配"TypeScript"
    
    console.log(pattern1.test(mainString)); // true
    console.log(pattern2.test(mainString)); // false
    
    // 不区分大小写匹配
    const caseInsensitivePattern = /javascript/i; // 'i' 标志表示不区分大小写
    console.log(caseInsensitivePattern.test(mainString)); // true
  • String.prototype.match()
    : 这个方法返回一个数组,包含所有匹配的结果(如果使用
    g
    全局标志),或者
    null
    如果没有找到。虽然也能用来判断,但通常比
    test()
    返回更多信息,如果只需要判断是否存在,
    test()
    更直接。

    const mainString = "Hello, world! Welcome to JavaScript.";
    const pattern1 = /world/;
    const pattern2 = /TypeScript/;
    
    console.log(mainString.match(pattern1)); // ["world", index: 7, input: "...", groups: undefined]
    console.log(mainString.match(pattern2)); // null
    
    if (mainString.match(pattern1)) {
        console.log("包含子串 (通过match):", pattern1);
    }

JavaScript中
includes()
indexOf()
和正则表达式,我该如何选择?

在我看来,选择哪种方法,确实是一个需要结合场景和个人偏好的问题。我经常会遇到这样的决策点。

如果你只是想简单地知道“有没有”某个子串,而且你的目标环境支持ES6(现在绝大多数现代浏览器和Node.js都支持),那么

String.prototype.includes()
无疑是最佳选择。它的代码可读性极高,一眼就能看出意图,而且语义清晰,返回的就是一个布尔值,省去了
!== -1
的判断。这在日常开发中,能省下不少心力。

String.prototype.indexOf()
,虽然稍微啰嗦一点,需要你额外判断返回值是否为
-1
,但它有一个独特的优势:它能告诉你子串第一次出现的位置。有时候,我不仅想知道有没有,还想知道“在哪里”,比如我想在找到子串后,从那个位置开始截取或者替换,这时候
indexOf()
就派上用场了。而且,如果你还在维护一些古老的项目,或者需要兼容IE浏览器,那么
indexOf()
就是你的可靠伙伴,因为它兼容性非常好。

至于正则表达式,那简直是字符串匹配领域的瑞士军刀。如果你的需求不仅仅是简单的子串匹配,比如你需要:

  • 不区分大小写地查找(例如,查找"javascript"而不论大小写)。
  • 查找符合特定模式的字符串(例如,查找所有数字、邮箱地址、URL等)。
  • 查找多个可能的子串中的任意一个。
  • 替换匹配到的模式。

这时候,

includes()
indexOf()
就显得力不从心了,正则表达式的强大之处才能真正体现出来。虽然它的语法可能初看起来有点晦涩,但一旦掌握,你会发现它能解决很多复杂的字符串处理问题。我个人在处理表单验证、文本解析时,几乎离不开它。当然,对于非常简单的匹配,用正则可能会有点“杀鸡用牛刀”的感觉,而且性能上可能不如直接的字符串方法。所以,我的原则是:简单需求用
includes()
,需要位置用
indexOf()
,复杂模式匹配果断上正则。

如何在JavaScript中实现不区分大小写的子串查找?

实现不区分大小写的子串查找,这在实际开发中非常常见,比如搜索功能,用户输入“apple”,你希望也能匹配到“Apple”或者“APPLE”。这里有几种方法,我通常会根据具体情况来选择。

1. 使用

toLowerCase()
toUpperCase()
转换后再比较

Hotpot.ai
Hotpot.ai

AI工具箱(图像、游戏和写作系列工具)

下载

这是最直观也最容易理解的方法,适用于

includes()
indexOf()
。它的核心思想是:将主字符串和要查找的子串都转换为统一的大小写(全部小写或全部大写),然后再进行比较。

const mainString = "Hello, JavaScript! Welcome to My Website.";
const searchLower = "javascript";
const searchUpper = "JAVASCRIPT";

// 转换为小写后使用 includes()
console.log(mainString.toLowerCase().includes(searchLower.toLowerCase())); // true
console.log(mainString.toLowerCase().includes(searchUpper.toLowerCase())); // true

// 转换为大写后使用 indexOf()
console.log(mainString.toUpperCase().indexOf(searchLower.toUpperCase()) !== -1); // true
console.log(mainString.toUpperCase().indexOf(searchUpper.toUpperCase()) !== -1); // true

这种方法的优点是简单易懂,兼容性好。但缺点是,如果你的主字符串非常长,或者你需要进行大量的查找操作,每次都对字符串进行

toLowerCase()
toUpperCase()
操作可能会带来一定的性能开销,因为它会创建一个新的字符串。在大多数Web应用场景下,这种开销通常可以忽略不计,但在性能敏感的场景下,可能需要考虑。

2. 使用正则表达式的

i
标志

这是处理不区分大小写匹配的“王道”方法,也是我个人最推荐的,尤其当你不只是判断包含,还可能涉及到更复杂的模式匹配时。正则表达式提供了一个

i
(ignore case)标志,直接告诉引擎在匹配时忽略大小写。

const mainString = "Hello, JavaScript! Welcome to My Website.";
const pattern = /javascript/i; // 'i' 标志表示不区分大小写

console.log(pattern.test(mainString)); // true
console.log(mainString.match(pattern)); // ["JavaScript", index: 7, input: "...", groups: undefined]

const anotherPattern = /website/i;
console.log(anotherPattern.test(mainString)); // true

使用正则表达式的

i
标志,代码更简洁,意图更明确。它直接在匹配层面解决了大小写问题,避免了创建新的字符串。对于复杂的模式,比如你不仅要不区分大小写,还要匹配“JS”或“Javascript”中的任意一个,正则表达式的优势就更加明显了:
/js(cript)?/i
。在我看来,只要涉及到不区分大小写,正则表达式几乎总是我的首选,除非是那种极其简单的、不需要任何模式的纯子串查找,我才会考虑
toLowerCase()

JavaScript查找子串时,有哪些常见的陷阱或性能考量?

在JavaScript中查找子串,虽然看似简单,但在实际开发中,确实会遇到一些需要注意的细节,甚至是一些不易察觉的“坑”,以及在特定场景下需要考虑的性能问题。

1. 空字符串的“陷阱”

这是一个我偶尔会忽略,但一旦遇到就可能导致逻辑错误的小细节。当你要查找的子串是一个空字符串(

""
)时,
includes()
indexOf()
的行为可能会让你感到意外:

const myString = "hello world";

console.log(myString.includes(""));    // true
console.log(myString.indexOf(""));     // 0
console.log("".includes(""));         // true
console.log("".indexOf(""));          // 0

includes("")
会返回
true
,而
indexOf("")
会返回
0
。这意味着,它们认为任何字符串都“包含”一个空字符串,并且空字符串总是在索引
0
处。这在大多数情况下是合理的(空字符串可以看作是任何字符串的子序列),但如果你的业务逻辑要求“只有当子串非空时才进行查找”,那么你就需要在调用这些方法之前,先对子串进行空字符串检查。我有时会忘记这一点,导致搜索结果不符合预期。

2. 性能考量:长字符串与高频操作

对于绝大多数前端应用场景,字符串查找的性能差异通常可以忽略不计。现代JavaScript引擎对这些内置方法都做了高度优化。然而,在以下特定情况下,你可能需要稍微留意:

  • 非常长的字符串: 如果你的主字符串有几十万甚至上百万个字符,并且你需要频繁地对其进行子串查找操作,那么不同方法的性能差异可能会显现出来。例如,
    toLowerCase()
    toUpperCase()
    会创建新的字符串,这会消耗内存和CPU。
  • 循环中的查找: 如果你在一个大型循环中,对大量字符串或同一个长字符串进行重复的子串查找,即使单次操作很快,累积起来的开销也可能变得显著。

在这种极端情况下,通常

indexOf()
includes()
会比正则表达式稍微快一些,因为它们是针对特定任务优化的。而正则表达式虽然功能强大,但其解析和匹配过程相对复杂,对于简单的纯子串查找,性能可能会略逊一筹。但话说回来,除非你真的遇到了性能瓶颈,否则我通常建议优先考虑代码的可读性和维护性。过早的优化往往是万恶之源。

3. 浏览器兼容性(历史遗留问题)

虽然现在已经不是大问题了,但如果你需要支持非常老的浏览器(比如IE11或更早),

String.prototype.includes()
是ES6(ECMAScript 2015)才引入的。这意味着在这些旧环境中,它将不可用。

// 在不支持ES6的环境中,这会抛出TypeError
// "abc".includes("b")

在过去,为了兼容性,我们通常会使用

indexOf() !== -1
来替代
includes()
。或者,你可以通过Polyfill来为旧浏览器添加
includes()
的支持。不过,随着浏览器更新迭代,现在很少需要为此特别担心了。但我偶尔还是会遇到一些遗留系统,需要我保持警惕。

4. Unicode与复杂字符集

JavaScript的字符串方法通常能很好地处理Unicode字符。例如,

"你好世界".includes("世界")
会正常工作。然而,对于一些更复杂的Unicode情况,比如组合字符(如
,它可能由
e
´
两个码点组成),或者一些特殊的语言环境下的字符匹配规则,简单的
includes()
indexOf()
可能无法满足所有需求。在这种情况下,可能需要借助更专业的Unicode库,或者更复杂的正则表达式模式。这通常是比较高级的场景,一般开发中较少遇到。

总的来说,在日常开发中,

includes()
indexOf()
是你的首选,它们简单高效。当需要处理复杂模式或不区分大小写时,正则表达式是不可替代的。了解这些方法的细微差别和潜在的“坑”,能帮助你写出更健壮、更高效的代码。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

537

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

372

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

727

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

470

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

388

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

989

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

652

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

537

2023.09.20

虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

25

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Swoft2.x速学之http api篇课程
Swoft2.x速学之http api篇课程

共16课时 | 0.9万人学习

PHP基础入门课程
PHP基础入门课程

共33课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号