全面解析JavaScript中对于字符串子串的查询方法

  1. 一、基本应用场景
  2. 二、String.prototype.includes()方法 (通用子串查找)
    1. 基本用法
    2. polyfill兼容
    3. 代码示例
    4. String.prototype.contains()方法 (特殊废弃)
  3. 三、String.prototype.indexOf()方法 (通用子串查找)
    1. 基本用法
    2. 返回值的奇怪效果
    3. 代码示例
    4. lastIndexOf()
    5. 使用indexOf统计一个字符串中某个字母的出现次数
  4. 四、String.prototype.startsWith() (特殊查找—查找开头)
    1. 基本用法
    2. polyfill兼容
    3. 代码示例
  5. 五、String.prototype.endsWith() ( 特殊查找—查找末尾 )
    1. 基本用法
    2. polyfill兼容
  6. 六、String.prototype.search( ) (特殊查找—正则查找)
    1. 基本用法
    2. 代码示例

一、基本应用场景


Q1:给定字符串a=”xxx”,给定字符串b=”xxxxxx”,判定a是否为b的子串。(基础手写实现方法)

1
2
3
4
5
6
7
8
9
10
11
12
function checkHas (longStr, shortStr) {
for (let i = 0; i < longStr.length - shortStr.length + 1; i++) {
for (let j = 0; j < shortStr.length; j++) {
if (shortStr.charAt(j) !== longStr.charAt(i+j)) {
break
} else if (j === shortStr.length - 1) {
return true
}
}
}
return false
}

JS的基本String对象的prototype方法当中,有很多方法能够实现这一操作。

二、String.prototype.includes()方法 (通用子串查找)


基本用法

1
str.includes(searchString[, position])
  1. 概述:****includes() 方法用于判断一个字符串是否包含在另一个字符串中,根据情况返回 truefalse
  2. 参数:searchString 要在字符串搜索的的字符串 ② position (可选)从当前字符串的哪个索引位置开始搜索子字符串,默认值为0。
  3. 返回值:如果当前字符串包含被搜索的字符串,就返回 true ;否则返回 false 。
  4. 特点:includes() 方法是区分大小写的。
1
'Blue Whale'.includes('blue'); // returns false

polyfill兼容

这个方法已经被加入到 ECMAScript 6 标准中,但未必在所有的 JavaScript 实现中都可以使用。然而,你可以轻松地 polyfill 这个方法,核心是通过另一个类似方法 indexOf() 来进行实现的,接下来我们会介绍到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}

if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}

代码示例

1
2
3
4
5
6
7
var str = 'To be, or not to be, that is the question.';

console.log(str.includes('To be')); // true
console.log(str.includes('question')); // true
console.log(str.includes('nonexistent')); // false
console.log(str.includes('To be', 1)); // false
console.log(str.includes('TO BE')); // false

String.prototype.contains()方法 (特殊废弃)

在 Firefox 18 - 39中,includes ( )方法的名称叫 contains()。由于下面的理由,在**bug 1102219**中,它被重命名为 includes()

据报道,在Firefox 17上,一些使用 MooTools 1.2的网站会崩溃掉。这个版本的MooTools会检查函数 String.prototype.contains() 是否存在,如果不存在的话,MooTools就添加它自己的函数。通过在Firefox 17中引入这个函数,检查更改的行为在一定程度上导致了基于MooTools的 String.prototype.contains() 函数的代码实现中断。结果是,当 MooTools的拓展 导致 MooTools 1.2.6 版本的发布,此实现在Firefox 17中不可用和 String.prototype.contains() 在随后一个版本Firefox 18上是可用的。

MooTools 1.3会强制使用它自己版本的函数 String.prototype.contains(),因此,依赖它的网站不会崩溃掉。然而,你应该注意此方法在 MooTools 1.3 签名和ECMAScript 6 签名中的不同(在第二个参数)。后来,**为了与ES6标准一致在MooTools 1.5版本及以上更改了签名。**

三、String.prototype.indexOf()方法 (通用子串查找)


基本用法

1
str.indexOf(searchValue [, fromIndex])
  1. 概述:**indexOf()** 方法返回调用它的 String 对象中第一次出现的指定值的索引,从 fromIndex 处进行搜索。如果未找到该值,则返回 -1。

  2. 参数1:searchValue
    要被查找的字符串值。如果没有提供确切地提供字符串,searchValue会被强制设置为”undefined”, 然后在当前字符串中查找这个值。举个例子:**'undefined'.indexOf()** 将会返回0,因为 undefined 在位置0处被找到,但是 'undefine'.indexOf() 将会返回 -1 ,因为字符串 'undefined' 未被找到。

  3. 参数2:fromIndex (可选)
    数字表示开始查找的位置。可以是任意整数,默认值为 0。如果 fromIndex 的值小于 0,或者大于 str.length ,那么查找分别从 0 和**str.length** 开始。举个例子,**'hello world'.indexOf('o', -5)** 返回 4 ,因为它是从位置0处开始查找,然后 o 在位置4处被找到。另一方面,**'hello world'.indexOf('o', 11)** (或 fromIndex 填入任何大于11的值)将会返回 -1 ,因为开始查找的位置11处,已经是这个字符串的结尾了。

  4. 返回值:查找的字符串 searchValue 的第一次出现的索引,如果没有找到,则返回 -1

  5. 特点:区分大小写字母

返回值的奇怪效果

若被查找的字符串 searchValue 是一个空字符串,将会产生“奇怪”的结果。如果 fromIndex 值为空,或者 fromIndex 值小于被查找的字符串的长度,返回值和以下的 fromIndex 值一样:

1
2
3
4
'hello world'.indexOf('') // 返回 0
'hello world'.indexOf('', 0) // 返回 0
'hello world'.indexOf('', 3) // 返回 3
'hello world'.indexOf('', 8) // 返回 8

另外,如果 fromIndex 值大于等于字符串的长度,将会直接返回字符串的长度str.length):

1
2
3
'hello world'.indexOf('', 11) // 返回 11
'hello world'.indexOf('', 13) // 返回 11
'hello world'.indexOf('', 22) // 返回 11

从前面一个例子可以看出,被查找的值是空值时,Javascript将直接返回指定的索引值。从后面一个例子可以看出,被查找的值是空值时,Javascript将直接返回字符串的长度。

代码示例

字符串中的字符被从左向右索引。第一个字符的索引(index)0,变量名为 stringName 的字符串的最后一个字符的索引是 stringName.length - 1

1
2
3
4
5
6
7
8
"Blue Whale".indexOf("Blue")       // 返回 0
"Blue Whale".indexOf("Blute") // 返回 -1
"Blue Whale".indexOf("Whale", 0) // 返回 5
"Blue Whale".indexOf("Whale", 5) // 返回 5
"Blue Whale".indexOf("", -1) // 返回 0
"Blue Whale".indexOf("", 9) // 返回 9
"Blue Whale".indexOf("", 10) // 返回 10
"Blue Whale".indexOf("", 11) // 返回 10

lastIndexOf()

与indexOf有着相同的用法,但是可以查找某字符串最后出现的情况。

1
2
3
4
5
6
7
8
9
10
11
var anyString = "Brave new world";

console.log("The index of the first w from the beginning is " + anyString.indexOf("w"));
// logs 8
console.log("The index of the first w from the end is " + anyString.lastIndexOf("w"));
// logs 10

console.log("The index of 'new' from the beginning is " + anyString.indexOf("new"));
// logs 6
console.log("The index of 'new' from the end is " + anyString.lastIndexOf("new"));
// logs 6

使用indexOf统计一个字符串中某个字母的出现次数

1
2
3
4
5
6
7
8
9
10
11
// 翻译:生存还是毁灭?这是个问题。(莎士比亚《哈姆雷特》)
var str = 'To be, or not to be, that is the question.';
var count = 0;
var pos = str.indexOf('e');

while (pos !== -1) {
count++;
pos = str.indexOf('e', pos + 1);
}

console.log(count); // displays 4

四、String.prototype.startsWith() (特殊查找—查找开头)


基本用法

1
str.startsWith(searchString[, position])
  1. 概述:****startWith( ) 方法用于判断一个字符串是否以另外一个给定的子字符串开头,根据情况返回 truefalse
  2. 参数:searchString 要在字符串搜索的的字符串 ② position (可选)从当前字符串的哪个索引位置开始搜索子字符串,默认值为0。
  3. 返回值:如果当前字符串的开头包含被搜索的字符串,就返回 true ;否则返回 false 。
  4. 特点:startWith() 方法是区分大小写的。

polyfill兼容

此方法已被添加至 ECMAScript 2015 规范之中,但可能不能在所有的现行 JavaScript 实现中使用。不过,你可以用以下的代码段为 String.prototype.startsWith() 制作 Polyfill

1
2
3
4
5
6
7
8
if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
value: function(search, pos) {
pos = !pos || pos < 0 ? 0 : +pos;
return this.substring(pos, pos + search.length) === search;
}
});
}

代码示例

1
2
3
4
5
var str = "To be, or not to be, that is the question.";

alert(str.startsWith("To be")); // true
alert(str.startsWith("not to be")); // false
alert(str.startsWith("not to be", 10)); // true

五、String.prototype.endsWith() ( 特殊查找—查找末尾 )


基本用法

1
str.endsWith(searchString[, length])
  1. 概述:**endsWith()**方法用来判断当前字符串是否是以另外一个给定的子字符串“结尾”的,根据判断结果饭回 true 或 **false**。
  2. 参数:searchString 要在字符串搜索的的字符串 ② length (可选)作为 str长度(非下标位置)。默认值为 str.length
  3. 返回值:如果传入的子字符串在搜索字符串的末尾则返回**true**;否则将返回 **false**。
  4. 特点:endsWith() 方法是区分大小写的。

polyfill兼容

1
2
3
4
5
6
7
8
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(search, this_len) {
if (this_len === undefined || this_len > this.length) {
this_len = this.length;
}
return this.substring(this_len - search.length, this_len) === search;
};
}

六、String.prototype.search( ) (特殊查找—正则查找)


基本用法

1
str.search(regexp)
  1. 概述:search() 方法执行正则表达式和String对象之间的一个搜索匹配。
  2. 参数:regexp 传入一个正则表达式对象,如果传入一个非正则表达式对象regexp,则会使用**new RegExp(regexp)**隐式地将其转换为正则对象
  3. 返回值:如果匹配成功,则 search() 返回正则表达式在字符串中首次匹配项的索引;否则,返回 -1
  4. 特点:对正则表达式进行灵活定义可以达到不同效果。

代码示例

1
2
3
4
5
var str = "hey JudE";
var re = /[A-Z]/g;
var re2 = /[.]/g;
console.log(str.search(re)); // returns 4, which is the index of the first capital letter "J"
console.log(str.search(re2)); // returns -1 cannot find '.' dot punctuation

参考资料:

1.https://developer.mozilla.org/zh-CN/docs/Web/JavaScript

2.https://www.cnblogs.com/Renyi-Fan/p/12691342.html

如有疑问,欢迎添加我的个人微信:

alexzhli