JS正则总结

本文最后更新于:2025年9月12日 下午

js正则

首先是用//包裹

const reg = /^1[345789]\d{9}$/g;

修饰符

  • i

ignoreCase : 忽略大小写

  • g

global : 全局匹配,即匹配全部满足的(不是贪婪匹配)

注意:

全局匹配是指遇到多少可以满足整个表达式的就匹配多少个,而贪婪匹配是指尽可能多地匹配单个字符

  • m

multiline : 多行匹配

比如/^\d$/gm就可以匹配多行的数字

正则的方法

  1. reg.test(str):用来匹配字符串是否可以匹配这个正则(正则对象上的方法, 频率最高)

  2. str.match(reg): 有多少个匹配成功的字符串并显示(字符串上的方法)

  3. reg.search(str): 返回匹配到的第一个字符的位置

  4. reg.source: 正则的内容

  5. reg.exec(str): 返回匹配到的第n个字符串

  6. reg.lastIndex: 第n个匹配字符串的索引

    注意:4, 5的函数都是基于global匹配的,因为只有可以匹配多个才能有第几个匹配

  7. str.split(reg): 很多时候我们都是用字符串来分隔字符的,但是我们也可以用正则

  8. str.replace(reg, char)

    这个js原生的replace是只能匹配第一个字符,也就是replaceFirstIndex

    如果我们使用全局的正则(g)来匹配,就能匹配替换所有了

开头和结尾固定匹配

  • 开头:^

  • 结尾:$

字符的范围

使用[]

eg:

const reg1 = /[0-3]/;
// 这就是匹配出现0~3的字符串
const reg2 = /[ac]/;
// 匹配有a或者c出现的字符串

如果^[]里面,代表着‘非’

eg:

const reg = /[^a]/;
// 匹配范围为不是a的所有字符

选择性匹配

使用|

eg:

const reg = /^(a|b|c)/;
// 匹配开头是a或者b或者c

重复多少次

使用{}

eg:

const reg1 = /0{9}/;
// 这就是匹配有9个0相邻的字符串
const reg2 = /0{3,5}/;
// 就是匹配3个到5个0
const reg3 = /0{1,}/;
// 匹配1到∞个0

默认的匹配是贪婪匹配,能多匹配就多匹配

重复次数扩展

  • *

    {0,} : 匹配当前字符0次到无数次

  • +

    {1,} : 匹配当前字符一次到无数次

  • ?

    {0,1} : 匹配当前字符零次或一次

取消贪婪匹配

默认的重复次数匹配是贪婪的,能匹配多个就多个

可以使用?来取消

eg:

const reg = /a{1,3}?/;
// 能匹配一个就不匹配两个

常见元字符

只要看到大写,就是小写的取反

  • .

    匹配所有单个字符,除了换行和结束符

  • \w

    word : 匹配字母

  • \d

    digit : 匹配数字

  • \s

    space : 匹配空白(不单指空格)

  • \b

    border : 匹配单词边界(前后有空格的字符)

  • \uxxxx

    unicode : 匹配汉字

子表达式

使用()可以在正则表达式中创建子表达式,这样做通常有两种作用

  1. 改变匹配的优先级

    和数学运算中的()类似,子表达式可以调整正则匹配的优先逻辑

    e.g. a|bc表示匹配a或者匹配bc,而(a|b)c表示匹配a或者b,然后匹配c

  2. 创建组

    下面将会详细介绍一下子表达式创建组的两种类型:捕获组引用组

捕获组

首先当使用()创建一个子表达式的时候就同时创建了一个捕获组,简单来说就是在匹配过程中,将括号内表达式匹配到的文本捕获并存储起来

const reg = /^(\d{4})-(\d{2})-(\d{2})$/;
const str = "2025-09-12"
console.log(str.match(reg));
/*
 结果为:
 [
  '2025-09-12',
  '2025',
  '09',
  '12',
  index: 0,
  input: '2025-09-12',
  groups: undefined
]
 */

可以看到结果中出现了捕获组的匹配内容

注意:若加上全局匹配(g)则结果中不会存储捕获内容

子表达式反向引用

引用组(通常被称为“反向引用”)是捕获组的一种扩展用法

使用\n来代表第n个子表达的引用(n为数字),从而将存储的捕获内容多次引用匹配

const reg = /(\d)\1\1/;
// 可以匹配出连续三个相同的数字

使用replace反向引用子表达式

使用$n来表示第n个子表达式的引用

const reg = /-(\w)/;
const str = 'the-first-name';
str.replace(reg, ($, $1) => {
  return $1.toUpperCase
})

非捕获分组

如果只是想运用子表达式但不想创建组,就可以使用(?:)来表示非捕获分组

const reg = /(?:ha)-ha,(haa)-\1/;
// 第一个ha就不是一个捕获组

零宽断言

如果我们希望在一个词语之间或之后进行内容匹配,就需要使用【零宽断言】功能

正向先行断言

使用(?=),表示在表达式之前进行内容匹配

const str = 'Date: 4 Aug 3PM';
const reg = /\d+(?=PM)/; // 匹配'3PM'中的'3'

正向后行断言

使用(?<=),表示在表达式后面进行内容匹配

const str = 'Product Code: 1064 Price: $5';
const reg = /(?<=\$)\d+/; // 匹配'$5'中的'5'

负向前行/后行断言

前后行断言都有他们的否定形式(匹配除了表达式中的内容),即负向的零宽断言,需要将括号中的=改为!即可

比如:

const str = 'Date: 4 Aug 3PM';
const reg = /\d+(?!PM)/; // 匹配'4'
const str = 'Product Code: 1064 Price: $5';
const reg = /(?<!\$)\d+/; // 匹配'1064'

常见问题

  1. 匹配任意长度字符串?

/[\d\D]*/

  1. 匹配AABB型?

/(.)\1/

  1. 字符串去重
const reg = /(\w)\1*/;
str.replace(reg, '$1')

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!