写这篇文章的原因有两点,第一是自我的知识整理和分享,第二是在工作中偶尔能要使用正则,当要用的时候方便知识查询,正则里面的元字符一大堆,上网搜有时候不知道去表述或Google关键字。
如何创建正则
字面量方式
这种方法最方便简单
// /pattern/flags
let reg = /\d/g
console.log(reg)
构造函数方式
这种方法比字面量麻烦,它的pattern为字符串,比起字面量的方式的优势在于可以动态的拼接
// 注意的一点是字面量里面写一个\, 这里要写两个\\
let reg = new RegExp('\\d', 'g')
console.log(reg)
js里与正则相关的函数
| 函数 | 参数 | 返回 |
|---|---|---|
| exec(arg1); | arg1: 字符串 | Array |
| test(arg1); | arg1: 字符串 | Boolean |
| replace(arg1, arg2) | arg1: 正则 或者 字符串 , arg2: 字符串 或 回调函数 | String |
下面是这三个函数使用的简单例子
let reg = /\d/g
console.log(reg.test('123abc'))
console.log(reg.exec('123tgb'))
console.log('123gb'.replace(reg, 'a'))
正则里面的括号
大括号 {}
正则表达式里面的大括号里面的内容为数字,表示前面的字符要重复多少次,简单的说{}用于设定匹配的长度。 看下面的例子:
// 匹配字符中b重复2到3次x重复2到3次
let reg = /b{2,3}x{2,3}/
console.log(reg.test('bbxx')) // true
console.log(reg.test('bbx')) // flase
// 字符串中b的重复次数必须大于等于2才能被匹配
let reg1 = /b{2,}/
中括号 []
中括号[]里的内容组成一个字符范围,只要目标字符串出现在其中就可以了,看下面的例子:
let reg = /b[143hg]b/
reg.test('b3b') // true, 3存在于143hg
reg.test('b143hgb') // false, 匹配模式为bxb x=1 或者 x = 3, x = 4, x = h, x=g
小括号 ()
小括号()常用于正则分组, 如下图:
javascript约定组名的方式如上图,下面看下例子加深你对捕获组的理解:
let reg = /a(\d(\w))/
// 用$&(可以理解为0组),替换reg匹配的内容, 打印的内容应该不变
console.log("fa5baf".replace(reg, '$&')) // fa5baf
// 用$1(第一组),替换reg匹配的内容
console.log("fa5baf".replace(reg, '$1')) // f5baf
// 用$1(第一组),替换reg匹配的内容
console.log("fa5baf".replace(reg, '$2')) // fbaf
小括号搭配|也能当中括号用,看下面的例子:
let reg = /a[143hg]b/
let reg1 = /a(1|4|3|h|g)b/
// reg 和 reg1的效果一样。() 搭配 | 组成匹配集合
元字符
正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。元字符使正则表达式具有处理能力。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
常用
| 代码 | 解释 |
|---|---|
| . | 匹配除换行符(\n, \r)以外的任意字符 |
| \w | 匹配字母或数字或下划线 |
| \W | 匹配任意不是字母,数字,下划线,汉字的字符 |
| \s | 匹配任意的空白符 |
| \S | 匹配任意不是空白符的字符 |
| \d | 匹配数字 |
| \D | 匹配任意非数字的字符 |
| \b | 匹配不是\w的开始的位置 |
| \B | 匹配是\w开头的位置 |
| 匹配字符串的开始 | |
| $ | 匹配字符串的结束 |
| | | 匹配组里表示或 |
重复
| 代码/语法 | 说明 |
|---|---|
| * | 重复零次或更多次 |
| + | 重复一次或更多次 |
| ? | 重复零次或一次 |
| {n} | 重复n次 |
| {n,} | 重复n次或更多次 |
| {n,m} | 重复n到m次 |
贪婪
| 代码/语法 | 说明 |
|---|---|
| *? | 重复任意次,但尽可能少重复 |
| +? | 重复1次或更多次,但尽可能少重复 |
| ?? | 重复0次或1次,但尽可能少重复 |
| {n,m}? | 重复n到m次,但尽可能少重复 |
| {n,}? | 重复n次以上,但尽可能少重复 |
断言
在使用正则表达式时,有时我们需要捕获的内容前后必须是特定内容,但又不捕获这些特定内容的时候
先行断言
| 代码/语法 | 说明 | 例子 |
|---|---|---|
| (?=exp) | 匹配exp前面的位置 | 正则: /\b\w+(?=ing\b)/g , 测试字符: I'm singing while you're dancing. 匹配: sing , danc |
| (?!exp) | 匹配后面跟的不是exp的位置 | 正则: /\d+(?!%)/ ,测试字符: 'that’s all 44 of them' 匹配: 44 |
后行断言
| 代码/语法 | 说明 |
|---|---|
| (?<=exp) | 匹配exp后面的位置 |
| (?<!exp) | 匹配前面不是exp的位置 |
超级实用的例子
如果下面正则表达式理解起来遇到困难,你可以复制它,去这个网站,这个网站可以根据正则生成图谱regexper
金额格式化
// \B可以理解为 '', 且''前面必须为\w 即 [0-9a-zA-Z]
// (?=) 先行断言
let reg = /\B(?=(\d{3})+(?!\d))/g
// console.log("123456789".replace(reg, ',')) // '' => ',' 123,456,789
邮箱
let reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
汉字
let reg = /^[\u4e00-\u9fa5]{0,}$/
ip
// (?:) 非捕获型
let reg = /((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))/
域名
let reg = /^(https?:\/\/)?([\w]([\w\-]{0,61}[\w])?\.)+[\w]{2,6}(\/)?$/
密码校验
let reg = /^(?=.*[0-9])(?=.*[a-zA-Z])(.{6,20})$/
// 密码6-20位, 必须包含字母和数字 不能包含空格
大家可以在评论区说下你常用正则表达式...