共计 4176 个字符,预计需要花费 11 分钟才能阅读完成。
基础知识
一 元字符
\b 单词分界空格
\d 数字 [0-9]
\w 英文 数字 下划线 [a-z0-9_]
\s 空白字符
反义
\D [^0-9]
\W [^a-z0-9_]
\S 非空白字符
. 任意字符 少用
.* 任意数量的不包含换行的字符 贪婪匹配
.? 懒惰 非贪婪匹配
\u4e00-\u9fa5 中文
二 量词
三 集合 字符类
[abc] 匹配 a /b/ c 任意字符
[^abc] 匹配除了 abc 外的任意字符
[a-z] 匹配 a 到 z 任意字符
// 注意:里面的 - 代表的是范围 例如
'ahd-fj-k'.replace(/[a-z]/g,'A') // 输出》AAA-AA-A
// 如果我想把斜杠也替换了呢 有两个方法
1. 利用转义符 \
'ahd-fj-k'.replace(/[a-z\-]/g,'B') // 输出 BBBBBBBB
2. 后面加多一个 -
'ahd-fj-k'.replace(/[a-z\-]/g,'B') // 输出 BBBBBBBB
//() 在集合里面默认被转义了 like this
//'(122)do('.replace(/[(\d)]/g,'A') 输出 AAAAAdoA
// 具体被转义范围不确定 欢迎普及补充
四 分支
123|34|567 // 匹配 123 或 34 或 567
五 边界 开始结束
^ // 代表开始 在 [] 代表非
$ // 代表结束
六 修饰符
g // 全局匹配 不写的话匹配完第一个就停止
i // 忽略大小写
m // 忽略换行
// 上面 3 可叠加使用
七 贪婪模式和非贪婪模式
js 默认贪婪模式 即最大可能的匹配
想要改成非贪婪模式在后面加个?
例子:'123456789'.replace(/\d{3,6}/,'XX') // 输出 XX
// 贪婪模式先匹配了最多的 6 个数字》X 剩下 3 个数字也算是符合就再多一个 X
'123456789'.replace(/\d{3,6}?/,'XX') // 输出 XXX
// 非贪婪模式 优先匹配了最低要求的 3 个数字一次 〉 3 个 X
八 分组与引用与捕获
分组是正则中非常强大的功能 可以让上面提到的量词作用与一组字符。
语法 圆括号包裹(*);
/([0-9])[a-z]+\1{3}/.test('2aa222') //true
/([0-9]+)[a-z]+\1/.test('12aa12') //true
/([0-9]+)[a-z]+\1/.test('12aa13') //false
// 这里需要注意一个问题。分组 "\1" 表示的并不是多个数字,而是和对应分组一模一样的数字
/<([a-z]+)>.*<\/\1>/.test('sdlk<div>sdjks</div>sdkl')
// true
并不是所有用 () 起来的就能被捕抓成为分组的。
下面就要说到 非捕抓分组可以提高性能和简化逻辑
用法:
**(***) // 识别成为可捕抓分组
(?:***) // 识别成为非捕抓分组 **
例子:把 a1b2c3d4 里面的数字都 +1
'a1b2c3d4'.replace(/(\d)/g,function($1){return $1*1+1})
// 输出 a2b3c4d5
把 2015-12-25 格式成 12 月 25 日 2015 年
'2015-12-25'.replace(/(\d{4})-(\d{2})-(\d{2})/g,'$2 月 $3 日 $1 年')
// 输出 12 月 25 日 2015 年
非捕抓例子:'2015-12-25'.replace(/(\d{4})-(?:\d{2})-(\d{2})/g,'$2 月 $3 日 $1 年')
// 第二个 () 里面有?: 所以它不被捕抓成分组。于是 $1 对应着 2015,$2 对应着 25
// 输出 25 月 $3 日 2015 年
九 前瞻
正则表达式从文本头部想稳步开始解析,文本尾部方向,称为“前”。
简单理解为 从左到右
前瞻就是 向前检查是否 属于断言 。
后顾 / 后瞻方向相反 但是 javascript 不支持后瞻。
正向前瞻 例子:'a2*3w4sb'.replace(/\w(?=\d)/g,'X') // 输出 X2*3X4sb
// 主角是 \w 只对它进行匹配。//(?=\d)这个就是断言 就是条件。只是条件不参与匹配
// 找 \w (英文 | 数字 | 下划线) 而且后面跟着 \d 数字的。// 所以符合的有 a2 的 a w4 的 w;
负向前瞻 例子:'a2*3w4sb'.replace(/\w(?!\d)/g,'X') // 输出 aX*XwXX
// 主角是 \w 只对它进行匹配。//(?!\d)这个就是断言 就是条件。只是条件不参与匹配
// 找 \w (英文 | 数字 | 下划线) 而且后面不是 \d 数字的。// 所以符合的有 2* 的 2 3w 的 3 4s 的 4 sb 的 s b 后面什么都没跟所以符合;
调用方法
Js 风格 调用 RegExp 对象的构造函数
var reg = new RegExp('^[a-z]+[0-9]$', 'gi')
Perl 风格 写在斜杠中
var reg = /^[a-z]+[0-9]$/gi
常用
-
test 返回布尔值
例子: /^\d+$/.test('12637') //true /^\d+$/.test('sdk') //false
- search 返回搜索到的对应位置 没有则 -1
// 注意 search 只查找一次,即使设置了 g。重复调用也是从起始位置开始
例子
‘ad1cd2c’.search(/d/g) //2 第一个数字的位置
‘adcd’.search(/d/g) //-1 找不到
-
replace 替换
('a1b2c3').replace(/\d/g,'数字') // a 数字 b 数字 c 数字
-
split 分割成数组 里面也能写正则。如果找不到匹配分割的把自己变数组
'a12b23c34'.split('1') //["a", "2b23c34"] 'a12b23c34'.split(/\d{2}/g) //["a", "b", "c", ""]'a12b23c34'.split(/[23]/g) //["a1","b","", "c", "4"] 'a12b23c34'.split(/[55]/g) //["a12b23c34"]
-
match 与 exec 返回数组 匹配到的字符串
两者相似又不同。写法上不一样
match 是字符串方法,写法为:str.match(reg)
exec 是正则表达式方法,写法为:reg.exec(str)写法:var reg = new RegExp("abc") ; var str = "3abc4,5abc6"; str.match(reg); var reg = new RegExp("abc") ; var str = "3abc4,5abc6"; reg.exec(str); --------------------------------------- 无子表达式非全局时:**exec 和 match 执行的结果是一样,均返回第一个匹配的字符串内容;** var reg = new RegExp("[a-z]+") ; var str = "1abc2,3abc4"; alert(str.match(reg)); alert(reg.exec(str)); // 都是输出 abc 无子表达式全局匹配:**match 执行了全局匹配查询;exec 找到一个匹配即返回。** var reg = new RegExp("[a-z]+","g") ; var str = "1abc2,3bcd4"; console.log(str.match(reg)); //["abc", "bcd"] console.log(str.match(reg)); //["abc", "bcd"] console.log(reg.exec(str)); //["abc"] console.log(reg.exec(str)); //["bcd"] //match 执行了全局匹配查询;而 exec 逐次返回。有子表达式 非全局:**match exec 都是返回结果 和分组 ** var reg = new RegExp("a(bc)") ; var str = "3abc4,5abc6"; console.log(str.match(reg)); //["abc", "bc"] console.log(reg.exec(str)); //["abc", "bc"] 有子表达式 全局:**match 忽略子表达式,只查找全匹配正则表达式并返回所有内容;exec 依然逐次返回结果 分组 ** var reg = new RegExp("a(bc)","g") ; var str = "3abc4,5abc6"; console.log(str.match(reg)); // ["abc", "abc"] console.log(str.match(reg)); // ["abc", "abc"] console.log(reg.exec(str)); // ["abc", "bc", index: 1] console.log(reg.exec(str)); // ["abc", "bc", index: 7]
随手简单正则
/^\d+$/.test('2l') // 只能输入数字
/^\d{n}$/.test('2222') // 只能输入 n 个数字
/^\d{n,}$/.test('22222') // 只能输入 n 个以上数字
/^\d{m,n}$/.test('22222') // 只能输入 m 到 n 个数字
/^[a-z]+$/i // 只能输入英文
/^[A-Z]+$/.test('SS’) // 只能输入大写英文
/^[0-9a-z]+$/i.test('1223ddsSSk') // 只能输入英文和数字
/^\w+$/.test('wS233_') // 只能英文数字下划线
/^[\u4e00-\u9fa5]+$/.test('大家看') // 纯中文
// 匹配手机号:手机号 1 开头 34568 第二位 数字任意 9 位
/^1[3|4|5|6|8]{1}\d{9}$/.test('13347834892')
// 匹配日期格式 YYYY-MM-DD
1/ 2 开头 3 个数字 - [0|1][1-9] - [0-1][1-9]
/^[1-9]\d{3}-[0-1]\d-[0-3]\d$/.test('2017-12-20')
// 过滤 html 标签: 以 < 开头 > 结尾的标签
'幕中闪着凶光。<br/><p/> 索拉卡'.replace(/<[^<>]+>/g,'')
// 简单版匹配 email 邮箱:英文数字下划线 @ 英文数字 .com
/^\w+\@[a-z0-9]+(.com)$/.test('@qq.com')
// 网上看到的 Email 地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
mark 一下 仅供参考 end
正文完
发表至: javascript
2019-04-22