正则表达式
- 正则表达式, 又名 "规则表达式"
- 由我们自己来书写 "规则", 专门用来检测 字符串 是否符合 "规则" 使用的
- 我们使用一些特殊的字符或者符号定义一个 "规则公式", 然后用我们定义好的 "规则公式" 去检测字符串是不是合格
构建正则表达式
- 想制定 "规则", 就必须要按照人家要求的方式来制定
- 把一些字母和符号写在
//中间的东西, 叫做正则表达式, 比如\abcdefg\ - 创建正则表达式有两个方式 字面量 和 构造函数创建
字面量方式
var reg = /abcdefg/
=> `//`内部可以书写任何表达式
构造函数创建
var reg = new RegExp('abcdefg')
=> '' 内部可以书写任何表达式
两种创建方式的区别
- 书写标识符
- 字面量方式,直接在正则后书写表示符
let reg1 = /abc/ig - 内置构造函数的方式,需要写在第二个参数中
let reg2 = new RegExp('abc','ig')
2.书写元字符
let reg1 = /\d\w\s.\./
console.log(reg1) // --> /\d\w\s.\./
let reg2 = new RegExp('\d\w')
console.log(reg2) //--> /dw/
在字符串中,如果书写了
\那么相当于转义符,将后边的字符转换为_有意义的字符 但是转换完成以后,\就会自动消失.那么正则拿到的就是一个具有特殊含义的字符d但是又因为正则中元字符必须是
\+d结合在一起才是一个元字符, 如果只有一个d那么就是一个普通的字母,没有任何特殊含义
解决方法:
在原本的
\前面再加一个\第一个\将第二个\转换为没有任意义的 普通义本。 最终正则拿到的就是一个没有特殊含义的 +d 然后按照正则的规则中,\+d就是一个元字符。代表的是数字0-9
let reg2 = new RegExp('\d\w')
console.log(reg2) //--> /\d\w/
正则的常用符号
元字符
-
.: 匹配非换行的任意字符 -
\: 转译符号, 把有意义的 符号 转换成没有意义的 字符, 把没有意义的 字符 转换成有意义的 符号 -
\s: 匹配空白字符(空格/制表符/...)
var reg = /\s/
var reg = /\S/
console.log(reg.test('1515%%#'))//false
console.log(reg.test(' as as'))//true
console.log(reg.test(' '))//true
\S: 匹配非空白字符\d: 匹配数字
var reg = /\d/
var str1 = 'ab'
var str2 = 'abc123'
var str3 = 'abc12315'
console.log(reg.test(str1)) => false
console.log(reg.test(str2)) => true
console.log(reg.test(str3)) => true
\D: 匹配非数字\w: 匹配数字字母下划线\W: 匹配非数字字母下划线
边界元字符
边界符是限定字符串的开始和结束的
^: 表示开头$: 表示结尾
var reg = /^\d{3,5}$/
var str = 'abc'
var str2 = 'abc123'
var str3 = '1'
var str4 = '1234567'
var str5 = '123'
var str6 = '12345'
console.log(reg.test(str)) // false
console.log(reg.test(str2)) // false
console.log(reg.test(str3)) // false
console.log(reg.test(str4)) // false
console.log(reg.test(str5)) // true
console.log(reg.test(str6)) // true
限定元字符
限定 前一个符号 出现多少次
*表示出现 0 ~ 正无穷次+表示出现 1 ~ 正无穷次?表示出现 0 ~ 1 次{n}表示出现 n 次{n,}表示出现 n ~ 正无穷次{n,m}表示出现 n ~ m 次
特殊符号
()表示限定一组元素
- 含义: 单独捕获;
- 含义: 一个整体;
|或; 含义: a|b 表示 a或者b[]字符合集, 表示包含 [] 中的任何一个元素都可以,只要满足其中一个即可[^]非字符合集,即不包含 [^] 中的某一个就行-到;至 ; 通常和[],[^]连用,
-
[0-9] 表示数字0到9, 等价于 \d -
[^0-9] 表示不包含数字0到9, 等价于 \D -
[a-z] 表示小写字母a到z -
[0-9a-zA-Z_] 等价于 \w
或的分界线
或的分界线为 小括号 或者 正则的边界
var reg = /^abc|def$/
//解析;满足 ^abc 或者 def$ 且只有三位
console.log(reg.test('abc1546')) //true
console.log(reg.test('151abc1546')) //false
var reg = /^ab(c|d)ef$/
//解析;满足 c 或者 d 且只有5位
console.log(reg.test('abcef')) //true
console.log(reg.test('abdef')) //true
console.log(reg.test('abcdef')) //false
重复元字符
- 语法: 符号:
\数字数字代表第几个小括号 - 含义:表示重复第n个小括号的内容,并且要求和小括号的内容完全一致
var reg = /^(abc|def)\1$/
console.log(reg.test('abcabc')) //true
console.log(reg.test('abcdef')) //false
console.log(reg.test('defdef')) //true
小案例:
需求,字符串是span或者p标签
var reg = /<(span|p)><\/\1>/
console.log(reg.test('<span></span>'))
标识符
- 写在表达式外面
- 用来描述整个正则表达式的
i
表示忽略大小写
- g
表示全局
var reg = /^[abcd]$/i
console.log(reg.test('a'))//true
console.log(reg.test('A'))//true
console.log(reg.test('n'))//false
捕获(还账)
语法:
正则.exec(字符串)
- 字符串没有符合正则规则的内容
捕获结果为null
var reg = /\d{3}/
console.log(reg.exec('abc'))//null
- 正则没有小括号,没有标识符 g
捕获到是一个数组,下标零是我们捕获到的值, 但是无论捕获多少次,都是从头开始第一个满足条件的
var reg = /\d{3}/
console.log(reg.exec('123abcd'))//[123]
- 有小括号
下标0 是符合正则规则的字符串 , 从下标1 开始是每个小括号捕获的数据
var reg = /(\d{3})(\w{3})(\d{3})/
console.log(reg.exec('123abc456'))
// ['123abc456', '123', 'abc', '456', index: 0, input: '123abc456', groups: undefined]
- 有全局标识符
第二次捕获时会从第一次捕获结束的位置开始捕获, 直到找不到内容会返回null, 再下一次捕获会重新开始,
var reg = /(\d{3})/g
console.log(reg.exec('123abc456'))//[123]
console.log(reg.exec('123abc456'))//[456]
console.log(reg.exec('123abc456'))//null
console.log(reg.exec('123abc456'))//[123]
正则两大特性(面试常问)
1.懒惰
- 每次捕获都是在下标0 的位置开始
- 解决: 在正则后添加 g
- 贪婪
- 每次捕获内容时尽可能多去捕获内容
- 解决:使用非贪婪限定符
- 在原有的限定符后面添加一个 ?
-
贪婪限定符: 非贪婪限定符: -
* *? -
+ +? -
? ?? -
{n} {n}? -
{n,} {n,}? -
{n,m} {n,m}?
-
var str = `<div class="box" id="box"><span></span></div>`
// 贪婪捕获
var reg = /<div.*>/
console.log(reg.exec(str))
// => <div class="box" id="box"><span></span></div>
// 非贪婪捕获
var reg1 = /<div.*?>/
console.log(reg1.exec(str))
// => <div class="box" id="box">
字符串的方法
字符串中有一些方法是可以和正则一起使用
search: 查找字符串中是否有满足条件的内容
- 语法:
字符串.search(正则) - 返回值: 有的话返回开始索引, 没有返回 -1
var reg = /\d{3}/
var str1 = 'hello123'
var str2 = 'hello'
console.log(str1.search(reg)) // 5
console.log(str2.search(reg)) // -1
match: 找到字符串中符合正则条件的内容返回
- 语法:
字符串.match(正则) - 返回值:
- 没有标识符 g 的时候, 是和 exec 方法一样
- 有标识符 g 的时候, 是返回一个数组, 里面是匹配到的每一项, 没有匹配到内容是返回的是 null
var reg = /\d{3}/
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.match(reg))
/*
['123', index: 5, input: 'hello123world456', groups: undefined]
0: "123"
groups: undefined
index: 5
input: "hello123world456"
length: 1
*/
console.log(str2.match(reg)) // -1
var reg = /\d{3}/g
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.match(reg)) // ['123', '456']
console.log(str2.match(reg)) // null
replace: 是将字符串中满足正则条件的字符串替换掉
- 语法:
字符串.replace(正则, 要替换的字符串) - 返回值: 替换后的字符串
var reg = /\d{3}/
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.replace(reg, '哈哈哈哈')) // hello哈哈哈哈world456
console.log(str2.replace(reg, '哈哈哈哈')) // hello world
var reg = /\d{3}/g
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.replace(reg, '哈哈哈哈')) // hello哈哈哈哈world哈哈哈哈
console.log(str2.replace(reg, '哈哈哈哈')) // hello world