前言
初级程序员调 API,中级程序员封装,高级程序员造轮子。
—— Frank Fang 方方老师
常用方法
字符串的方法,全部定义在String.prototype
上。
1. charAt()
传入一个索引值,返回值是索引值对应的单个字符
语法: str.charAt(index)
示例:
let str = 'Hi~ Jeffrey'
console.log(str.charAt(4)) // J
2. includes()
用于检查字符串中是否包含某一段字符串,会返回一个布尔值。
语法:
str.includes(searchString[, position])
参数说明:
- searchString:搜索的字符串,不能是正则表达式。
- position: 从哪个索引值开始搜索,默认为 0。
示例:
const str = 'Hello Jeffrey'
str.includes('Jeffrey') // true
3. match()
字符串调用这个方法后,若通过正则校验则会返回一个数组,数组中包含匹配项信息;若未通过则返回 null
。
语法: str.match(regexp)
参数说明:
- regexp:可以是任何实现了
Symbol.match
方法的对象,比如正则表达式。
返回值:
取决于正则表达式是否有g
标识(g
flag)以及是否有匹配项。
- 如果没有匹配项:返回
null
。 - 如果有匹配项,返回数组。
- 如果有
g
flag,所有的匹配项都会返回,但不含捕获组信息。数组包含以下键值:<number>
:从 0 开始的数组索引,依次对应所有匹配项。length
:匹配项的数量。
- 如果没有
g
flag,只返回第一个匹配项,以及捕获组信息。数组包含以下键值:0
:对应第一个匹配项length
:匹配项和捕获组的数量和。index
:匹配项的第一个字符在原字符串中的索引值input
:原始字符串groups
:命名捕获组,而非普通捕获组。
- 如果有
正则表达式「捕获组」相关语法:
字符集 | 含义 |
---|---|
(x) | 捕获组 Capturing group |
(?<Name>x) | 命名捕获组 Named capturing group |
(?:x) | 非捕获组 Non-capturing group |
示例:
// 1. 利用 ^ 与 $ 进行全字符串匹配,不要加 g flag
let name1 = 'I love sunshine', reg1 = /^[a-zA-Z\s]+$/
console.log(name1.match(reg1))
// ['I love sunshine', index: 0, input: 'I love sunshine', groups: undefined]
// 2. 匹配所有非连续的单词时,加 g flag
let name2 = 'I love sunshine love', reg2 = /love/g
console.log(name2.match(reg2)) // ['love', 'love']
// 3. 如果想用捕获组或命名捕获组,不要加 g flag
let name3 = 'I love sunshine', reg3 = /love (sunshine)/
console.log(name3.match(reg3))
// ['love sunshine', 'sunshine', index: 2, input: 'I love sunshine', groups: undefined]
let name4 = 'I love sunshine', reg4 = /love (?<key>sunshine)/
console.log(name4.match(reg4))
// ['love sunshine', 'sunshine', index: 2, input: 'I love sunshine', groups: { key: 'sunshine' }]
4. matchAll()
返回一个包含所有匹配正则表达式的结果及捕获组的迭代器,此方法是 str.match(regexp)
的“更新、改进”的变体。
与 match
相比有 4 个区别:
- 它返回一个包含匹配项的可迭代对象,而不是数组。我们可以用
Array.from()
将其转换为一个数组。如果用for..of
来遍历可迭代对象,也可以不需要Array.from()
。 - 正则参数 regexp 必须设置为全局模式(g flag)。
- 每个匹配项均以一个数组形式返回(返回格式与不带修饰符 g 的
str.match()
相同)。 - 如果没有结果,则返回的是一个空的可迭代对象而不是
null
。(RegExpStringIterator {}
)
语法:
str.matchAll(regexp)
参数说明:
regexp 必须设置为全局模式(g flag),否则会抛出异常。
返回值:
一个迭代器(不可重用,结果耗尽需要再次调用方法,获取一个新的迭代器)。
示例:
let str = '<h1>Hello</h1>'
let regexp = /<(.*?)>/g // 捕获组
// 命名捕获组 /<(?<group1>.*?)>/g
let match1 = str.matchAll(regexp)
console.log(match1) // RegExpStringIterator {},不是数组,而是一个可迭代对象
for (let arr of match1) {
console.log(arr)
// ['<h1>', 'h1', index: 0, input: '<h1>Hello</h1>', groups: undefined]
// ['</h1>', '/h1', index: 9, input: '<h1>Hello</h1>', groups: undefined]
}
5. replace()
可以把字符串中符合要求的字符修改为指定字符。
语法:
str.replace(regexp|substr, newSubStr|function)
示例:
let tel = '134 1234 1234'
console.log(tel.replace(/ /g,'-')) // 134-1234-1234
6. replaceAll()
可以把字符串中所有符合要求的字符替换为指定字符
示例:
let tel = '134 1234 1234'
console.log(tel.replaceAll(' ','-')) // 134-1234-1234
7. split()
分割字符串,括号内传入的字符表示要以什么字符分割,最终返回一个数组。
示例:
const str = "Hello World";
const target = str.split(' ');
console.log(target); // ["Hello", "World"];
8. substring()
截取字符串。传入两个参数,分别是截取的起始索引和终止索引(在该索引处结束提取字符串)。
语法:
str.substring(indexStart[, indexEnd])
参数说明:
- 如果任一参数小于 0,则被当作 0。
- 如果 indexStart 大于 indexEnd,则 substring 的执行效果就像两个参数调换了一样。
示例:
let anyString = "Mozilla";
// 输出 "Moz"
console.log(anyString.substring(0,3));
console.log(anyString.substring(3,0));
console.log(anyString.substring(3,-3)); // indexEnd 小于 0,被视作 0
console.log(anyString.substring(-2,3));
9. slice()
截取字符串。传入两个参数,分别是截取的起始索引和终止索引。产生一个新字符串,不修改原字符串。
语法:
str.slice(indexStart[, indexEnd])
参数说明:
- 如果 indexEnd 小于 0,则终止索引就是倒数第 |indexEnd| 个。如果超出字符串长度,indexEnd 视为 0。
示例:
let anyString = "Mozilla"
// 输出 "Moz"
console.log(anyString.slice(0, 3))
console.log(anyString.slice(0, -4)) // 提取第 1 个字符到倒数第 4 个字符(不含倒数第 4 个)
10. substr()
截取字符串。不推荐使用此方法,以便软件最大程度地跨平台应用。用substring()
、slice()
方法代替。如果有代码用了 substr()
看懂即可,先不要修改,等出了问题再修改。
it's defined in Annex B: Additional ECMAScript Features for Web Browsers, which is normative optional for non-browser runtimes.
语法:
str.substr(start[, length])
参数说明:
- 如果 start 为负值,则 substr 把它作为从字符串末尾倒数第|start|个开始的一个字符索引。
示例:
let str = "abcdefghij";
console.log("(1,2): " + str.substr(1,2)); // (1,2): bc
console.log("(-3,2): " + str.substr(-3,2)); // (-3,2): hi
11. toLowerCase() / toUppercase()
将字符串转变大小写
示例:
const username = 'Jeffrey'
console.log(username.toLowerCase()) // jeffrey
console.log(username.toUpperCase()) // JEFFREY
12. trim()
去除字符串左右两端的空白字符,对字符串中间的空格无效
示例:
const username = ' ca t '
console.log(username.trim()) // ca t
13. indexOf()
找到指定字符串首次出现时,第一个字符的索引值
示例:
const str = 'Hi, dude~ Nice to meet you, dude~'
console.log(str.indexOf('dude')) // 4
14. lastIndexOf()
找到指定字符串最后一次出现时,第一个字符的索引值
const str = 'Hi, dude~ Nice to meet you, dude~'
console.log(str.lastIndexOf('dude')) // 28
15. search()
找到指定正则表达式首次匹配时的索引。没有匹配项则返回 -1。
参数说明:
如果传入字符串,会自动通过new Regexp(obj)
语法转换为正则表达式。
语法:
str.search(regexp)
示例:
const str = "hey Jude";
const re = /[A-Z]/
str.search(re) // 4
16. charCodeAt()
返回一个 0 ~ 65536 范围间的十进制数,这个数字代表 UTF-16 字符给定索引的码点。
示例:
// 先把字符串转为 UTF-16 编码格式
const emoji = "😄"; // "\uD83D\uDE04"
emoji.charCodeAt(0) // 55357 '\uD83D'
emoji.charCodeAt(1) // 56836 '\uDE04'
17. codePointAt()
返回一个十进制数,这个数字代表 UTF-16 字符给定索引的码点(code point)。
当字符串之间存在代理对(surrogate pair),它与charCodeAt()
就有区别了。
- 如果码点位置是代理对的高位(UTF-16 high surrogate),则返回整个代理对的码点;
- 如果码点位置是代理对的低位(UTF-16 low surrogate),则只返回低位的码点。
示例:
// 先把字符串转为 UTF-16 编码格式
const emoji = "😄"; // "\uD83D\uDE04"
emoji.codePointAt(0) // 128516 '\u{1F604}'
emoji.codePointAt(1) // 56836 '\uDE04'
常用属性
字符串的属性,实际上是包装之后的 String 对象才有。执行完,包装对象自动销毁。
1. length
返回字符串的 UTF-16 编码格式的代码单元(code units)的长度。
const emoji1 = "😄" // "\uD83D\uDE04"
console.log(emoji1.length) // 2
const emoji2 = "👩🦱" // "\uD83D\uDC69\u200D\uD83E\uDDB1"
console.log(emoji2.length) // 5
如果想获取字符串中的字符数,而不是 UTF-16 代码单元长度,用扩展运算符。这种情况下每个代理对(surrogate pair)将会被视作一个字符。
const emoji1 = "😄" // "\uD83D\uDE04"
console.log([...emoji1].length) // 1
const emoji2 = "👩🦱" // "\uD83D\uDC69\u200D\uD83E\uDDB1"
console.log([...emoji2].length) // 3,相当于 "👩\u200D🦱"
遍历字符串
1. 遍历每个字符
同样地,每个代理对将会被视作一个字符。
// 可以通过 break, continue 等语法提前结束循环
for(const char of 'A😄C'){
console.log(char) // A, 😄, C
}
或者
// 无法提前退出循环
[...'A😄C'].forEach((char, i)=>{console.log(char)}) // A, 😄, C
2. 遍历每个 UTF-16 代码单元
let str = '😄'
for (let i = 0; i < str.length; i++) {
console.log(`"\\u${str.charCodeAt(i).toString(16)}"`)
// "\ud83d"
// "\ude04"
}