常用正则匹配总结

89 阅读2分钟

当涉及到处理文本数据时,正则表达式是一种非常强大的工具。它可以帮助我们在字符串中搜索、匹配和替换特定的模式。

在这篇博客中,我总结了一些常见的正则表达式基础知识,旨在帮助读者更好地理解和应用正则表达式。

限定符

语法描述
a*a 出现0次或多次
a+a 出现1次或多次
a?a 出现0次或1次
a{6}a 出现6次
a{2,6}a 出现2-6次
a{2,}a 出现两次以上

或运算符

语法描述
(a | b)匹配 a 或者 b
(ab) | (cd)匹配 ab 或者 cd

字符类

语法描述
[abc]匹配 a 或 b 或 c
[a-c]与上式意义相同
[a-fA-F0-9]匹配大小写的 a 到 f以及数字
[^0-9]匹配非数字字符

元字符

语法描述
\d匹配数字字符
\D匹配数字字符
\w匹配单词字符(英文,数字,下划线)
\W匹配单词字符
\s匹配空白符(包含换行符,tab)
\S匹配非空白符
.匹配任意字符
\b标注字符的边界,全字匹配
^,$匹配行首,行尾

贪婪/懒惰匹配

所谓懒惰匹配,就是匹配尽可能少的字符.

语法: *? 或者 +? ; ? 表示懒惰模式,必须跟在*或者+后面使用.

例如: 测试字符串 aababaabab,当我们使用 a.*b 去匹配时, 得到的结果为 aababaabab,而当我们使用a.*?b去匹配,会得到aabaababab两个结果.

捕获与预查

  1. ()可以捕获符合子表达式的字符串

例如: 使用(\d{4})-(\d{2})-(\d{2})去测试字符串2021-12-13,返回结果为['2021-12-13','2021','12','13']

  1. (?:)可以不捕获符合子表达式的字符串

例如: 使用(\d{4})-(?:\d{2})-(\d{2})去测试字符串2021-12-13,返回结果为['2021-12-13','2021','13']

  1. exp1(?=exp2)正向预查: 匹配在exp2之前的exp1.

例如: a(?:b)表示匹配一个aa,并且aa后面要紧跟bb.

  1. exp1(?!exp2)负向预查: 匹配后面不是exp2exp1.

例如: a(?!b)表示匹配一个aa,并且aa后面不能是bb.

例如: ^(?!dog)(?!cat).{2,6}$表示匹配不以dogcat开头的2~6个字符.

应用场景示例

  • 中文正则表达式: [\u4E00-\u9FA5]

  • 十六进制颜色: ^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$

  • 密码强度校验:

    1. 弱:6~15位的纯数字,纯小写字母或纯大写字母: (\d{6,10})|([a-z]{6,10}|([A-Z]){6,15})
    2. 中:6~15位的数字+字母,字母+特殊,数字+特殊:(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,15}

    解释: (?![\d]+$)排除纯数字,(?![a-zA-Z]+$)排除纯字母,(?![^\da-zA-Z])排除纯特殊字符串

    1. 强:6~15位,包含大写字母和特殊字符: ^(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{6,15}
  • 用户名: [a-zA-Z0-9_-]{4,16}

JavaScript中动态拼接正则

在JavaScript中我们不能使用常规的字符串拼接方式来拼接正则表达式,必须借助eval方法才能正确拼接.

var con = "[\d]+";
var regCor = eval(`/${con}/`);
var regErr = "/" + con + "/";
console.log(regCor.test("321321")); // True
consolg.log(regErr.test("321321")); // Error: test not a function

eval(): 函数会将传入的字符串当做 JavaScript 代码进行执行。

reg.test(str): 测试 reg 是否匹配 str ,可以返回 True ,反之返回 False

reg.exec(str): 测试 reg 是否匹配 str ,返回一个数组,第一项为完整的匹配内容,后面的项为子匹配.

参考资料与练手习题

力扣练手题:

  1. 2315. 统计星号 - 力扣(Leetcode)

  2. 2299. 强密码检验器 II - 力扣(Leetcode)

  3. 1807. 替换字符串中的括号内容 - 力扣(Leetcode)

字节面试

千位分隔符转换,即将 10000001000000 转化为 1,000,0001,000,000 的形式。

let rawNum = "100000"
let regex = /\B(?=(\d{3})+$)/g;
console.log(rawNum.replace(regex, ',')) 

正则表达式 /\B(?=(\d{3})+$)/g 的含义如下:

  • \B:匹配非单词边界,表示匹配一个位置,该位置前后都是数字字符或非数字字符。
  • (?=(\d{3})+$):正向肯定预查,表示匹配一个位置,该位置后面是以每三个数字为一组的结尾。