JavaScript 正则表达式

一、正则表达式基础概念

正则表达式(Regular Expression,简写为 regex、regexp 或 RE),是通过单个字符串描述、匹配一系列符合特定句法规则的字符串搜索模式,核心作用是实现文本搜索文本替换

  • 本质:由字符序列构成的搜索模式,可简单(如单个字符)可复杂(如多规则组合)。
  • JS 中创建方式
    1. 字面量形式:var reg = /pattern/modifiers;(常用,性能更优)
    2. RegExp 构造函数:var reg = new RegExp("pattern", "modifiers");(动态生成正则时使用)

二、正则表达式的核心构成

正则表达式由 定界符元字符模式修饰符表达式 四部分组成,四者协同定义匹配规则。

1. 定界符

用于包裹正则表达式的 “边界符号”,JS 中最常用 正斜线 /,格式为 /表达式/修饰符

  • 示例:/\w+/g/ 是定界符,\w+ 是表达式,g 是修饰符)
  • 说明:定界符仅用于标记正则的开始与结束,不参与实际匹配。

2. 元字符:正则的 “规则核心”

元字符是具有特殊含义的字符,用于定义匹配规则,分为四大类:原子筛选方式原子集合原子数量限定边界控制

(1)原子的筛选方式

通过特定符号定义 “匹配哪些单个原子(字符 / 字符组)”,核心是 “选什么”。

筛选符号含义描述示例
``二选一,匹配 “” 前后任意一项`/er/g` 匹配字符串中的 “e” 或 “r”
[]匹配方括号内任意一个原子/[27]/g 匹配 “2” 或 “7”
[^]匹配 “除方括号内原子外” 的任意字符/[^0-9]/g 匹配非数字字符
-范围连接符(仅在 [] 内生效),匹配范围两端的字符及中间所有字符/[5-9]/g 匹配 5-9 的数字;/[a-zA-Z]/g 匹配所有大小写字母
()模式单元,将括号内的多个原子视为 “一个整体原子”/(lo)/g 匹配完整的 “lo”,而非单独的 “l” 或 “o”

示例代码

var str = 'h2ATel?#9lo27 _w5or7ld';
console.log(str.match(/[a-zA-Z0-9_]/g)); // 匹配数字、字母、下划线
console.log(str.match(/[^abcdefghij]/g)); // 匹配除 a-j 外的所有字符
console.log(str.match(/2|lo/g)); // 匹配 "2" 或 "lo"
(2)原子的集合(预定义字符类)

为常用的 “字符范围” 提供简写,简化正则书写,核心是 “快速选一类”。

预定义符号含义描述等价写法示例
.匹配除换行符(\n)、回车符(\r)外的任意单个字符[^\n\r]/h./g 匹配 “h” 后面跟任意一个字符(如 “h2”“he”)
\d匹配任意数字[0-9]/\d/g 匹配字符串中所有数字
\D匹配任意非数字[^0-9]/\D/g 匹配字符串中所有非数字
\s匹配任意空白字符(空格、制表符 \t、换行 \n 等)[\f\n\r\t\v ]/\s/g 匹配字符串中的所有空格
\S匹配任意非空白字符[^\f\n\r\t\v ]/\S/g 匹配字符串中的所有非空格
\w匹配数字、大小写字母、下划线[0-9a-zA-Z_]/\w/g 匹配字符串中的数字、字母、下划线
\W匹配非数字、非字母、非下划线[^0-9a-zA-Z_]/\W/g 匹配字符串中的特殊符号(如 “?”“#”)

注意:匹配特殊字符(如 /.:)时,需用反斜杠 \ 转义(如 \/ 匹配 /\. 匹配 .)。

示例代码

var str = "he12341llo21 world562 http://789455ww78w.baidu.com3";
console.log(str.match(/\/|\./g)); // 匹配 "/" 或 "."
console.log(str.match(/\d/g)); // 匹配所有数字
console.log(str.match(/\w/g)); // 匹配所有数字、字母、下划线
(3)原子数量限定(量词)

定义 “某个原子 / 原子组连续出现的次数”,核心是 “选多少个”。

量词符号含义描述等价写法示例
{n}匹配前面的原子恰好 n 次-/\d{3}/g 匹配连续 3 个数字(如 “123”“455”)
{n,}匹配前面的原子至少 n 次-/\d{2,}/g 匹配连续 2 个及以上数字(如 “21”“562”)
{n,m}匹配前面的原子n 到 m 次(包含 n 和 m)-/\d{2,5}/g 匹配连续 2-5 个数字(如 “12”“78945”)
+匹配前面的原子至少 1 次{1,}/\d+/g 匹配 1 个及以上数字(等价于 /\d{1,}/g
*匹配前面的原子0 次或多次{0,}/\d*/g 匹配 0 个或多个数字(空字符也会匹配)
?匹配前面的原子0 次或 1 次(可选){0,1}/\d?/g 匹配 0 个或 1 个数字

关键概念:贪婪匹配 vs 非贪婪匹配

  • 贪婪匹配(默认):尽可能匹配最长的符合规则的字符串,如 /^a.+c/ 匹配 “apcdefc” 中的 “apcdefc”(从 a 到最后一个 c)。
  • 非贪婪匹配(惰性匹配):尽可能匹配最短的符合规则的字符串,在量词后加 ? 启用,如 /^a.+?c/ 匹配 “apcdefc” 中的 “apc”(从 a 到第一个 c)。

示例代码

var str = "he12341llo21 world562";
console.log(str.match(/\d{3}/g)); // 匹配连续 3 个数字(如 "123")
console.log(str.match(/\d+/g)); // 匹配 1 个及以上数字(如 "12341" "21")

var str2 = 'apcdefc';
console.log(str2.match(/^a.+c/)); // 贪婪匹配:["apcdefc"]
console.log(str2.match(/^a.+?c/)); // 非贪婪匹配:["apc"]
(4)边界控制

定义 “匹配的位置边界”,核心是 “在哪里匹配”。

边界符号含义描述示例
^匹配字符串的开头(多行模式下匹配每行开头)/^he/g 匹配以 “he” 开头的字符串(如 “hello” 中的 “he”)
$匹配字符串的结尾(多行模式下匹配每行结尾)/ld$/g 匹配以 “ld” 结尾的字符串(如 “world” 中的 “ld”)
\b匹配单词边界(单词与非单词的分隔处,如空格、符号)/\bis/g 匹配 “This is an island” 中的 “is”(独立单词)
\B匹配非单词边界(单词内部的字符间隔)/is\B/g 匹配 “island” 中的 “is”(非独立单词)

示例代码

// 需求:必须以字母开头,后面只能是数字、字母、下划线
var reg = /^[a-zA-Z]\w*$/;
var str = 'w345234sdf';
console.log(reg.test(str)); // true(符合规则)

var str2 = "This is an island";
console.log(str2.search(/\bis/)); // 4(匹配独立的 "is",索引为 4)
console.log(str2.search(/is\b/)); // 4(同上,匹配独立 "is" 的结尾)
console.log(str2.search(/\Bis/)); // 11(匹配 "island" 中的 "is",索引为 11)

3. 模式修饰符

用于修改正则的匹配行为,写在定界符 // 之后,常用修饰符如下:

修饰符含义描述示例
i不区分大小写匹配/[a-z]/gi 匹配所有字母(无论大小写)
g全局匹配(找到所有匹配项,而非找到第一个就停止)/l/g 匹配 “hello” 中的两个 “l”
m多行匹配(使 ^ 匹配每行开头,$ 匹配每行结尾)/^he/gm 匹配 “hello world\nhello jack” 中的两个 “he”(每行开头的 “he”)

示例代码

var str = 'ywr9yh3rhyFRE91h';
console.log(str.match(/[a-z]/g)); // 仅匹配小写字母(如 "y" "w")
console.log(str.match(/[a-z]/gi)); // 不区分大小写,匹配所有字母(如 "y" "F" "R")

var str2 = 'hello world \nhello jack';
console.log(str2.match(/^he/g)); // 仅匹配第一行开头的 "he":["he"]
console.log(str2.match(/^he/gm)); // 多行匹配,匹配两行开头的 "he":["he", "he"]

三、JS 中常用正则场景示例

以下是开发中高频使用的正则表达式,可直接参考或调整:

验证场景正则表达式说明
非空验证/^\S+$/不能全是空白字符(空格、换行等)
邮箱验证/^[\w-]+@([\w-]+\.)+[a-zA-Z0-9]+$/支持常见邮箱格式(如 786087136@qq.comran_yi-hang@163.com.cn
手机号验证/^1[356789]\d{9}$/匹配中国大陆手机号(11 位,开头为 13/15/16/17/18/19)
URL 验证/^https?\:\/\/([\w-]+\.)+\S+$/匹配 HTTP/HTTPS 协议的 URL(如 http://www.baidu.comhttps://www.jd.com.cn?name=jack
汉字验证/^[\u4e00-\u9fa5]+$/仅匹配纯汉字(单个汉字用 /[\u4e00-\u9fa5]/
日期格式(yyyy-mm-dd)`/^[1-9]\d{3}-(0[1-9]1[0-2])-(0[1-9]1[0-9]2[0-9]3[0-1])$/`匹配合法日期(如 2024-05-20,避免 2024-13-32 这类无效日期)
身份证号码/^\d{15}(\d{2}[0-9X])?$/匹配 15 位或 18 位身份证(18 位末位支持 X)
用户名(字母开头,含字母 / 数字 / 下划线)/^[a-zA-Z]\w{5,15}$/6-16 位,以字母开头,后续可跟数字、字母、下划线

四、JS 中常用正则方法

正则表达式需结合 JS 方法才能实现具体功能,常用方法分为 “字符串方法” 和 “RegExp 对象方法”:

方法类型方法名功能描述示例
字符串方法str.match(reg)查找所有匹配项,返回数组(无匹配则返回 null)"hello".match(/l/g) → ["l", "l"]
字符串方法str.search(reg)查找第一个匹配项的索引(无匹配则返回 -1)"This is it".search(/is/) → 2
字符串方法str.replace(reg, replacement)替换匹配项,返回新字符串"hello".replace(/l/g, "x") → "hexxo"
字符串方法str.split(reg)按匹配项拆分字符串,返回数组"a1b2c".split(/\d/) → ["a", "b", "c"]
RegExp 方法reg.test(str)检测字符串是否匹配,返回布尔值(true/false)/^1[3-9]\d{9}$/.test("13800138000") → true
RegExp 方法reg.exec(str)查找单个匹配项,返回详细信息数组(无匹配则返回 null)/l/g.exec("hello") → ["l", index: 2, input: "hello"]