正则表达式完整参考手册(JavaScript 版,兼容绝大多数语言)

0 阅读2分钟

说明:不同语言(Java/Python/.NET)少量语法有差异,标注【JS专属】【不支持JS】;前端 RegExp、String.match/replace/test 直接可用。 正则两大写法:

// 字面量(推荐,/pattern/flags) const reg = /abc/i // 构造函数(字符串要转义 \ → \) const reg = new RegExp(‘abc’, ‘i’) “`

一、修饰符(Flags 标志)

标志名称说明
gglobal全局匹配,找到所有结果,不是只匹配第一个
iignoreCase忽略大小写
mmultiline多行模式:^ 匹配行首、$ 匹配行尾(不是整个字符串首尾)
sdotAll. 可以匹配换行符 \n(JS ES2018+)
uunicode开启Unicode模式,正确处理emoji、生僻字
ysticky粘性匹配,从 lastIndex 位置开始紧挨着匹配

二、元字符(特殊字符)

这些字符有特殊含义,如果要匹配字符本身,必须加反斜杠 `` 转义: . \ / * + ? | ( ) [ ] { } ^ $

元字符含义
.匹配任意单个字符(除换行 \n;开启s后包含换行)
\转义符,把特殊字符变成普通字符,或者引出转义序列
开头;多行模式下为每行开头
$结尾;多行模式下为每行结尾
()分组、捕获组;也用于优先级
[]字符集,匹配括号内任意一个字符
{}量词,限定重复次数
*量词:0次或多次
+量词:1次或多次
?量词:0次或1次;也用来开启非贪婪、正向预查

三、字符集 [] 与字符范围

  • [abc]:匹配 a、b、c 任意一个
  • [a-z]:小写字母 a~z
  • [A-Z]:大写字母 A~Z
  • [0-9]:数字 0~9
  • [a-zA-Z0-9]:字母+数字
  • [^abc]:取反,匹配除a/b/c以外任意字符(^ 在 [] 里面是取反,外面是行首)
  • [.-]:- 放在开头/结尾就是普通减号,不会当成范围

⚠️ 在 [] 里面:. * + ? () 不需要转义

四、预定义字符类(简写)

简写等价说明
\d[0-9]数字
\D[^0-9]非数字
\w[a-zA-Z0-9_]单词字符:字母、数字、下划线
\W[^a-zA-Z0-9_]非单词字符
\s[ \t\n\r\f\v]空白:空格、制表符、换行、回车
\S[^ \t\n\r\f\v]非空白
\n换行符line feed
\r回车符carriage return
\t制表符 Tab
\b单词边界单词和非单词交界处(不占字符,零宽)
\B非单词边界不是单词边界

重点:\b 是零宽,不消耗字符,比如 /\bcat\b/ 匹配独立单词 cat,不匹配 category

五、量词(重复次数)

写法含义
{n}恰好 n 次
{n,}至少 n 次
{n,m}n ~ m 次(包含两端)
*{0,} 0次或多次
+{1,} 1次或多次
?{0,1} 0次或1次

贪婪 vs 非贪婪(非常高频坑)

默认贪婪匹配:尽可能多匹配;在量词后面加 ? → 非贪婪(尽可能少匹配)

  • \d+ 贪婪:1234 → 匹配 1234
  • \d+? 非贪婪:1234 → 先匹配 1 示例:

示例:

'<a>1</a><a>2</a>'.match(/<a>.*</a>/)  // 贪婪,拿到全部
'<a>1</a><a>2</a>'.match(/<a>.*?</a>/) // 非贪婪,分开匹配

六、分组(Capture Group 捕获组)

1. 捕获组 (pattern)

  • 括号内匹配到的内容会单独捕获,可以反向引用、提取
  • 编号:从左到右 $1 $2 $3 …
const reg = /(\d{4})-(\d{2})-(\d{2})/
const res = '2026-11-11'.match(reg)
// res[1] = 2026,res[2]=11,res[3]=11

替换时使用:

'2026-11-11'.replace(reg, '$2/$3/$1') // → 11/11/2026

2. 非捕获组 (?:pattern)

只分组、不捕获,不占用 $1 $2 编号,性能更好

/(?:abc|def)123/

3. 命名捕获组【ES2018+ JS支持】(?<name>pattern)

给分组起名字,可读性强

const reg = /(?<year>\d{4})-(?<month>\d{2})/
const m = '2026-11'.match(reg)
console.log(m.groups.year, m.groups.month)

4. 反向引用 \1 \2

在正则内部引用前面捕获到的分组内容 /(\w)\1/ → 匹配连续重复字符,如 aa、bb

注意:正则字面量里 \1;字符串构造正则要写 \1

七、零宽断言(预查,零宽,不消耗字符,JS ES2018完整支持)

零宽 = 只做判断,不把字符吞进匹配结果

语法名称含义
(?=expr)正向先行断言后面必须是 expr
(?!expr)负向先行断言后面不能是 expr
(?<=expr)正向后行断言前面必须是 expr
(?<!expr)负向后行断言前面不能是 expr

示例:

​// 数字后面带px,只提取数字,不要px ‘100px 20rem’.match(/\d+(?=px)/g) // [100] ​
// 前面是¥的数字 ‘¥99,abc88’.match(/(?<=¥)\d+/g) // [99] ​
// 不能以0开头的数字(先行) /^(?!0)\d+$/ 

​八、注释与优先级

  1. 优先级(从高到低) `` → ()、(?...) → [] → 量词 * + ? {} → ^ $ \b → |
  2. 注释:(?#注释) 【⚠️ JS原生RegExp不支持】 JS想写注释:用 x 修饰符的是其他语言(PCRE),JS不支持,只能分开写注释

九、JS 常用正则方法

String 方法

  • str.match(reg):匹配,返回数组;不带g只返回第一个+分组;带g返回全部匹配结果(无分组)

  • str.matchAll(reg):【ES2020】带g,返回迭代器,同时拿到分组,推荐复杂提取

  • str.replace(reg, newVal|fn):替换,支持 $1 $2 $& $' $“

    • <!--MATH_PH_1-->1:分组1

    • $`:匹配内容前面文本

    • $‘:匹配内容后面文本

  • str.search(reg):返回匹配下标,找不到-1,不支持g

  • str.split(reg):按正则分割

RegExp 对象方法

  • reg.test(str):返回布尔,是否匹配(⚠️ 带g时会变动 lastIndex,坑很多!)
  • reg.exec(str):一次匹配,返回匹配数组+分组;带g会自动向后走 lastIndex

⚠️ 大坑:/abc/g 反复 test 会因为 lastIndex 导致时而true时而false

十、常用正则模板(开箱即用)

// 手机号(国内11位)
/^1[3-9]\d{9}$/

// 邮箱
/^[\w-]+(.[\w-]+)*@([\w-]+.)+[a-zA-Z]{2,7}$/

// 纯数字
/^\d+$/

// 纯字母
/^[a-zA-Z]+$/

// 数字+字母,6-16位(密码简单校验)
/^[a-zA-Z0-9]{6,16}$/

// 中文(UTF-8)
/^[\u4e00-\u9fa5]+$/

// URL简易匹配
/^https?://[^\s]+/

// 身份证(18位)
/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/

十一、常见踩坑清单

  1. . 不匹配换行,需要加 s 标志 /./s
  2. ^ $ 是字符串首尾,多行模式 m 才变成行首尾
  3. [] 中 . * + ? 不用转义;- 放中间会变成范围
  4. 量词默认贪婪,需要 ? 开启非贪婪
  5. 后行断言 (?<=) 老浏览器不支持(IE完全不支持)
  6. \w 包含下划线,很多人误以为只是字母数字
  7. 构造函数 new RegExp 字符串里面 `` 必须双写 \d
  8. test() + g 全局标志,lastIndex 状态残留

十二、PCRE / .NET / Python 差异简要提示

  • PCRE(PHP):支持 (?#注释)、x 宽松模式、递归 (?R)
  • .NET:后行断言支持不定长;JS后行断言只能固定长度
  • Python re:re.VERBOSE 宽松注释模式,re.A 控制 \w 范围