JavaScript 有关正则方法的总结

发布时间:9/2/2025
更新时间:9/2/2025
展示:348

Javascript 与正则相关的方法常用到的一般在 RegExpString 这两种变量类型中, 为方便记忆, 避免每次都去 MDN 查阅, 在这里做一下总结, 方便后续查阅

RegExp

test()

测试字符串中是否存在匹配模式的子串。

参数 :

string : 要测试的字符串。

返回

boolean: 字符串是否匹配正则, 匹配为true, 不匹配为false

示例

// 一个字符串中是否包含某个子串
/ab/.test('abc') // true

// 字符串中是否包含数字
/[0-9]/.test('123') // true

exec()

在一个指定字符串中执行一个搜索匹配。返回一个包含匹配信息的数组。

参数 👍

string : 要测试的字符串。

返回

null : 没有匹配到信息

Array : 匹配的字符串数组
返回的数组除了包含匹配的字符串外,这个数组还包含以下属性:

  • index 匹配开始的位置
  • input 原始字符串
  • groups 命名捕获组属性

示例 :

匹配字符串中的字符 a ,拿到匹配索引等信息

const result = /a/.exec('bca1tda')
resutl // ['a']
result.index // 2
result.input // bca1tda
result.groups // undefined

捕获字符串中的年月日。

const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const str = "今天是2023-10-15,天气很好";
const result = regex.exec(str); 
result // ['2023-10-15', '2023', '10', '15']
result.groups // {year: '2023', month: '10', day: '15'}

exec() 返回的匹配字符串数组会包含组信息,组就是正则中用()包裹的内容

匹配所有

一般来说 exec() 方法是用来匹配字符串中的第一个符合正则的子串 , 但是可以搭配lastIndex属性可以实现遍历所有匹配的子串。

const regex = /a/g;
const str = 'abcdefa';
let result;
while ((result = regex.exec(str)) !== null) {
  console.log(`找到 ${result[0]} 起始位置 ${result.index} 结束位置${regex.lastIndex}`);
}
// 找到 a 起始位置 0 结束位置1
// 找到 a 起始位置 6 结束位置7

这里的 lastIndex 是正则表达式的一个可读可写的整型属性,用来指定下一次匹配的起始索引。

每一次 exec() 匹配成功, 就会自动更新正则表达式对象的 lastIndex 属性, 这样下一次调用 exec() 方法时, 就会从新的开始位置开始匹配。

String

match()

exec 一样可以在字符串中进行搜索匹配。返回一个包含匹配信息的数组。

参数 :

regex : 一个正则表达式对象

返回值 :

没有匹配到信息时,返回 null
匹配到信息时,返回包含匹配信息的数组, 数组内容取决于是否存在全局标志 g

  • 没有全局标志 g, 返回结果和exec() 相同
  • 有全局标志 g, 只返回匹配的字符串数组,不包含匹配位置等信息

示例

// 没有全局标志 g, 返回结果和exec() 相同
const result = 'abcdefa'.match(/a/) 
result // ['a']
result.index // 0
result.input // abcdefa
result.groups // undefined

// 有全局标志 g, 只返回匹配的字符串数组
const result = 'abcdefa'.match(/a/g) 
result // ['a', 'a']
result.index // undefined
result.input // undefined
result.groups // undefined

matchAll()

在字符串中匹配与正则表达式相符的所有结果,就是match的全局匹配版本。

参数 :

  • regex : 一个正则表达式对象

返回值 :

一个包含捕获组信息的迭代器,迭代返回的每项格式与 regex.exec() 返回的数组相同。

示例

前面 exec 需要搭配 lastIndex 才能获取所有匹配子串的捕获信息不同, 使用 matchAll 可以一步到位

const result = 'abcdefa'.matchAll(/a/g) 
result.forEach(item => {
  console.log(item)
})
// ['a', index: 0, input: 'abcdefa', groups: undefined]
// ['a', index: 6, input: 'abcdefa', groups: undefined]

replace()

搜索字符串中与正则表达式匹配的部分,并将其替换为新的子串。

参数 :

  • pattern : 一个字符串或一个正则表达式
  • replacement : 一个字符串或函数, 用于替换匹配的子串

返回值 :

返回一个新字符串,其中部分匹配 pattern 的部分都被替换为 replacement。

示例 :

将日期字符串中的-替换为/

const str = 'a1cXXXa2c'
'2023-08-06'.replace('-','/') // 2023/08-06'

可以使用 $n 来引用组, 其中 n 是组的索引

// 利用捕获组可以 替换匹配的子串
'a1cXXXa2c'.replace(/a([0-9])c/g,'$1') // '1XXX2'

指定函数作为替换项

如果 replacement 是一个函数, 则需要返回一个字符串用来替换匹配的子串,该函数的格式如下

function replacer(match, p1, p2, ..., offset, string, groups) {
  return replacement
}

其中:

  • match : 匹配的子串
  • p1, p2, ... : 捕获组的子串, 有多少个捕获组, 就有多少个参数
  • offset : 匹配的子串在原字符串中的索引
  • string : 原字符串
  • groups : 命名捕获组属性

这些参数和 exec() 方法匹配的结果相似, 就是 p1, p2, ... 有点难理解, 举几个例子加深理解

'a1a2a3'.replace(/a/g,(match,offset,str,groups)=>{
  console.log(match,offset,str,groups)
  return 'b'
})
// 输出结果
// a 0 a1a2a3 undefined
// a 2 a1a2a3 undefined
// a 4 a1a2a3 undefined
// 'b1b2b3'

这里为什么没有p1, p2, ... 这几个参数, 是因为正则表达式中没有捕获组, 所以没有捕获组的子串, 正则中用()包裹起来的为组

'a1a2a3'.replace(/a([0-9])/g,(match,p1,offset,str,groups)=>{
  console.log(match,p1,offset,str,groups)
  return 'b'+p1
})
// 输出结果
// a1 1 0 a1a2a3 undefined
// a2 2 2 a1a2a3 undefined
// a3 3 4 a1a2a3 undefined
// 'b1b2b3'

也就是说, 要记住自己在正则中加了几个组, p1, p2, ...这里就会有几个参数, 不然很容易把参数搞错顺序

replaceAll()

replace() 类似,但会替换所有匹配的子串,而不仅仅是第一个。

参数 :

  • pattern : 一个字符串或一个正则表达式,这里的正则表达式必须设置全局标志 g, 不然会抛出错误
  • replacement : 一个字符串或函数, 用于替换匹配的子串

返回值 :

返回一个新字符串,其中所有匹配 pattern 的部分都被替换为 replacement。

示例 :

"aabbcc".replaceAll("b", ".") // "aa..cc"

search()

执行正则表达式搜索,返回第一个匹配项的索引。类似于 indexOf(),但支持正则表达式。

参数 :

  • regexp : 一个正则表达式

返回值 :

匹配成功的索引,失败则返回 -1

示例 :

查询字符串中第一个 a2或者a3 出现的位置

const index = 'a1a2a3'.search(/a3|a2/) 
console.log(index) // 2

split()

使用正则表达式(或固定字符串)作为分隔符,将字符串分割成一个字符串数组。

参数 :

  • separator : 一个字符串或正则表达式, 用于指定分隔位置
  • limit : 一个非负整数,指定数组中包含的子字符串的数量限制。

返回值 :

一个数组,包含分割后的子字符串。

示例 👍

使用正则表达式匹配逗号、空格、连字符或点号

const str = 'one,two three-four.five'
const result1 = str.split(/[\s,\-\.]+/)
console.log(result1 ) // ['one', 'two', 'three', 'four', 'five']

// 指定 limit
const result2 = str.split(/[\s,\-\.]+/, 3);
console.log(result2 ) // ['one', 'two', 'three']

总结

test() 适合判断字符串中 "是否有" 的问题

exec()、match()、matchAll() 适合在字符串中进行搜索,拿到匹配的字符串、匹配位置等信息,单独想拿到位置信息可以用 search()。
全局匹配的match() 和 matchAll() 都可以匹配所有,但是带有 g 标志的 match() 只能拿到匹配结果,没有所有匹配结果的位置信息。

replace() 和 replaceAll() 适合对字符串中的部分内容进行替换。并且带有 g 标志的 replace() 和 replaceAll() 是等价的,并没有什么不同

split() 适合分割字符串

目录
  • RegExp
    • test()
    • exec()
  • String
    • match()
    • matchAll()
    • replace()
    • replaceAll()
    • search()
    • split()
  • 总结