cover

走马

陈粒

regular-expression

regular-expression

正则表达式基础#

NOTE

正则的所有规则,都可以归为两类:「匹配什么字符」「匹配多少个」

1.匹配「单个字符」的核心符号#

符号大白话解释极简例子(测试文本:abc123ABC_@ 换行匹配结果
普通字符匹配和自身完全一模一样的字符a匹配文本里的a
.(点号)匹配除换行符\n外的任意单个字符(万能牌)a.c匹配abca1c,不匹配a\nc
[](字符集)匹配括号内的任意 1 个字符(多选一),支持范围写法[abc][0-9][a-z]前者匹配a/b/c,中者匹配任意数字,后者匹配任意小写字母
[^](排除字符集)匹配除了括号内的任意 1 个字符[^0-9]匹配所有非数字的字符
\d匹配任意 1 个数字,等价于[0-9](超高频)\d匹配1/2/3
\w匹配任意 1 个字母、数字、下划线_,等价于[a-zA-Z0-9_]\w匹配a/b/c/1/2/3/_,不匹配@/空格
\s匹配任意 1 个空白字符(空格、Tab 制表符、换行符\n\s匹配文本里的空格、换行
\D/\W/\S对应上面三个的反义:非数字、非字母数字下划线、非空白\D匹配所有不是数字的字符
WARNING
  • 解决「要找什么字 / 内容」的问题,每个符号只匹配1 个字符
  • ^有两个完全不同的含义![]里面是「排除」,在[]外面是「字符串开头」,千万别搞混。

2.匹配「数量」的核心量词#

符号大白话解释极简例子(测试文本:ac abc abbc abbbc匹配结果
*匹配前面的字符,出现 0 次或多次(可有可无,越多越好)ab*c匹配acabcabbcabbbc
+匹配前面的字符,出现 1 次或多次(至少 1 次,不能没有)ab+c匹配abcabbcabbbc,不匹配ac
?匹配前面的字符,出现 0 次或 1 次(最多 1 次,也就是「可选」)ab?c匹配acabc,不匹配abbc
{n}匹配前面的字符,正好出现 n 次(超高频!)\d{11}匹配正好 11 个数字(手机号核心规则)
{n,}匹配前面的字符,至少出现 n 次\d{6,}匹配至少 6 个数字
{n,m}匹配前面的字符,出现 n~m 次(闭区间)\d{6,12}匹配 6 到 12 个数字(密码长度规则)
WARNING
  • 解决「要找的字符,重复出现多少次」的问题,必须跟在「单个字符符号」后面使用
  • * = + ?,也就是说*等于+?的并集
  • 贪婪模式 vs 非贪婪模式
  • 量词默认是贪婪模式:会尽可能匹配最长的符合规则的内容
    • 例子:正则a.*b,测试文本a123b456b,会匹配整个a123b456b,而不是最短的a123b
  • 非贪婪模式:在量词后面加?,会匹配最短的符合规则的内容
    • 例子:正则a.*?b,测试文本a123b456b,只会匹配a123b

进阶#

1.匹配「位置」的锚点#

NOTE

不匹配具体的字符,只匹配「文本的位置」,核心用来做格式验证

符号大白话解释高频用法
^匹配整个字符串的开头^1:只有以 1 开头的文本才会被匹配
$匹配整个字符串的结尾\d$:只有以数字结尾的文本才会被匹配
\b匹配单词的边界(单词和空格 / 标点之间的位置)\bhello\b:匹配hello world里的 hello,不匹配helloworld里的 hello
WARNING
  • \b 是保证匹配的是整体,而不是中间片段,具体的整体匹配对象应该在两个\b之间。
  • 经典案例:验证 11 位国内手机号
    • 正确正则:^1[3-9]\d{9}$
    • 解释:^开头必须是 1,第二位是 3-9(国内手机号规则),后面跟 9 个数字,$结尾,确保整个文本正好 11 位,不会匹配到 12 位数字里的片段。

2.分组与分支#

1. 分支 |#

大白话:或者,匹配左边的规则,或者匹配右边的规则。

例子:abc|def,匹配abc或者defjpg|png|gif,匹配三种图片后缀。

2. 分组 ()#

核心作用有两个,是正则进阶的核心:

  1. 把规则当成一个整体

    例子:(ab)+,匹配abababababab(ab 重复 1 次或多次);如果不加括号ab+,是匹配a后面跟 1 个或多个b,比如ababbabbb,完全是两个意思。

  2. 捕获分组,支持反向引用

    括号里匹配到的内容会被自动存起来,从左到右,第一个括号是\1(匹配时引用)/$1(替换时引用),第二个是\2/$2,以此类推。

    超实用经典案例:日期格式批量转换

    需求:把2024-05-20改成05/20/2024

    正则:(\d{4})-(\d{2})-(\d{2})

    替换内容:$2/$3/$1

    解释:第一个括号捕获年份20241),第二个捕获月份051),第二个捕获月份`05`(2),第三个捕获日期20($3),替换时直接调换顺序即可。

补充:非捕获分组(?:)

只把规则当整体,不存储匹配内容,不占用分组编号,适合不需要反向引用的场景,比如(?:ab)+,匹配结果和(ab)+一致,但不会存储ab到分组里。

文章目录

✨️ 复制成功,转载请标注本文地址