正则表达式
1. 认识正则
正则表达式(规则表达式)
我们自己来书写规则, 然后专门用来检测 字符串 是否符合规则
创建正则
-
var reg = /正则在这里边/
-
var reg = new RegExp('正则写在这里边')
var reg = /abc/
console.log(reg)
var reg2 = new RegExp('abcd')
console.log(reg2)
2. 正则的常用方法
1. 匹配
test 匹配字符串是否符合正则规则
true 符合规则 false 不符合
var reg = /abc/ // 匹配一段字符串中是否包含 'abc'
var str1 = 'a'
var str2 = 'ab'
var str3 = 'abc'
var str4 = 'abcd'
var str5 = 'a1b2c3'
console.log(reg.test(str1)) // false
console.log(reg.test(str2)) // false
console.log(reg.test(str3)) // true
console.log(reg.test(str4)) // true
console.log(reg.test(str5)) // false
2. 捕获
语法: 正则.exec(字符串)
- 字符串没有符合正则规则的内容
- 捕获的结果为 null
- 正则没有小括号, 没有标识符 g
- 捕获到的是一个数组, 下标0 是我们捕获到的值
- 但是不管捕获多少次, 都是从 下标[0]开始, 第一个满足条件的
- 有小括号
- 下标0 是符合正则规则的字符串
- 从 下标1 开始, 时每个小括号单独捕获出来的内容
- 有标识符 g
- g 叫做全局标识符
- 第二次捕获的时候, 会从第一次捕获结束的位置开始进行捕获
- 直到找不到内容, 会返回一个 null
- 然后再下一次捕获的时候, 会从字符串开始位置重新捕获
// 1. 字符串没有符合正则规则的内容
var reg = /\d{3}/
console.log(reg.exec('qwertyuiop'))
// 2. 正则没有小括号, 没有标识符 g
var reg = /\d{3}/
console.log(reg.exec('qwe123rty456uiop789'))
console.log(reg.exec('qwe123rty456uiop789'))
// 3. 有小括号
var reg = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/
var num = '411381200401311234'
console.log(reg.exec(num))
// 4. 有标识符 g
var reg = /\d{3}/g
var str = 'qwe123rty456uiop789'
console.log(reg.exec(str)) // [0]: 123
console.log(reg.exec(str)) // [0]: 456
console.log(reg.exec(str)) // [0]: 789
console.log(reg.exec(str)) // null
console.log(reg.exec(str)) // [0]: 123
3. 正则的元字符
正则表达式的符号, 由两种符号组成
1. 元字符
- 正则的规则符号
- 普通文本--正则的规定符号
2. 修饰符
- 修饰整个正则表达式的符号
普通元字符
-
- \d 表示 一位 数字(0-9)
-
- \D 表示 一位 非数字(除了0-9)
-
- \s 表示 一位 空白内容(空格, 缩进)
-
- \S 表示 一位 非空白内容
-
- \w 表示 一位 数字(0-9)字母(a-zA-Z)下划线(_)
-
- \W 表示 一位 非数字字母下划线的内容
-
- . 表示 一位 非换行内容
-
- \ 表示 转义符
// 1. \d
var reg = /\d/ // 匹配字符串中 包含一位 数字
console.log(reg.test('abcd')) // false
console.log(reg.test('abcd#$%^&*(')) // false
console.log(reg.test('123456789')) // true
// 2. \D
var reg = /\D/ // 匹配字符串中 包含一位 非数字
console.log(reg.test('abcd')) // true
console.log(reg.test('abcd#$%^&*(')) // true
console.log(reg.test('123456789')) // false
// 3. \s
var reg = /\s/ // 匹配字符串中 包含一位 空白内容
console.log(reg.test('123456!@#$%qwerty')) // false
console.log(reg.test('123456! @#$%qwerty')) //true
// 4. \S
var reg = /\S/ // 匹配字符串中 包含一位 非空白内容
console.log(reg.test('123456!@#$%qwerty')) // true
console.log(reg.test('123456! @#$%qwerty')) // true
console.log(reg.test(' ')) // false
// 5. \w
var reg = /\w/ // 匹配字符串中 包含一位 数字(0-9)字母(a-zA-Z)下划线(_)
console.log(reg.test('abc')) // true
console.log(reg.test('a1b2c3')) // true
console.log(reg.test('a1b2_c3')) // true
console.log(reg.test('!@#$%^&')) // false
// 6. \W
var reg = /\W/ // 匹配字符串中 包含一位 非数字字母下划线
console.log(reg.test('abc')) // false
console.log(reg.test('abc123')) // false
console.log(reg.test('abc123_')) // false
console.log(reg.test('!@#$%')) // true
console.log(reg.test(' ')) // true
// 7. .
var reg = /./ // 匹配字符串中 包含一位 非换行的任意内容
console.log(reg.test('@#$%^')) // true
console.log(reg.test('asdf')) // true
console.log(reg.test('123')) // true
console.log(reg.test('\n')) // \n 在 JS 中代表换行
// 8. \
var reg = /\d\.\d/ // . 表示非换行的任意内容, \. 表示一个小数点, 没有任何特殊含义
/**
* var reg = /4.5/
* var reg = /\d.5/
* var reg = /\d\.5/
* var reg = /\d\.\d/
*/
console.log(reg.test('abc')) // false
console.log(reg.test('5.7')) // true
console.log(reg.test('100')) // false
4. 正则的边界元字符
1. ^ 表示开头
2. $ 表示结尾
当 开头与结尾 共同使用时, 表示 字符串 必须是 规则里的内容
var reg = /^\d/ // 表示 字符串开头需要是一位数字
console.log(reg.test('100abc')) // true
console.log(reg.test('abc999')) // false
// var reg = /\d$/ // 表示 字符串结尾需要是一位数字
console.log(reg.test('100abc')) // false
console.log(reg.test('abc999')) // true
var reg = /abc/ // 表示字符串中 包含 'abc'
console.log(reg.test('abcd')) // true
var reg1 = /^abc$/ // 表示 字符串 必须是 'abc'
console.log(reg1.test('abcd')) // false
5. 正则的限定元字符
限定了 前一个符号 出现多少次
-
-
- 表示 0~正无穷次
-
-
-
- 表示 1~正无穷次
-
-
- ? 表示 0~1 次
-
- {n} 表示 限定 n 次
-
- {n,} 表示 限定 最少 n 次
-
- {n,m} 表示 限定 最少 n 次, 最多 m 次
// 1. *
var reg = /^\d*$/
console.log(reg.test('abc')) // false
console.log(reg.test('_99')) // false
console.log(reg.test('66634567890')) // true
// 2. +
var reg = /^\d+$/
console.log(reg.test('abc')) // false
console.log(reg.test('_99')) // false
console.log(reg.test('66634567890')) // true
console.log(reg.test(' ')) // false
console.log(reg.test('!')) // false
// 3. ?
var reg = /^\d?$/
console.log(reg.test('6')) // true
console.log(reg.test('99')) // false
// 4. {n}
var reg = /^\d{3}$/
console.log(reg.test('6')) // false
console.log(reg.test('99')) // false
console.log(reg.test('777')) // true
console.log(reg.test('4444')) // false
// 5. {n,}
var reg = /^\d{3,}$/
console.log(reg.test('6')) // false
console.log(reg.test('99')) // false
console.log(reg.test('777')) // true
console.log(reg.test('4444')) // true
// 6. {n,m}
var reg = /^\d{3,4}$/
console.log(reg.test('6')) // false
console.log(reg.test('99')) // false
console.log(reg.test('777')) // true
console.log(reg.test('4444')) // true
console.log(reg.test('12345')) // false
6. 特殊元字符
- ()
- 含义1: 单独捕获(欠着)
- 含义2: 一个整体
- |
- 含义: 或 a|b
- [] 包含 中括号内 其中一个即可
在中括号中可以书写任意数量的符号,但是字符串只要满足其中一个即可
- [^] 非 不包含
在中括号内可以书写任意数量的符号,只要字符串不是其中某一个类型就行
- 到 至 通常和 [] [^] 连用
/[0-9]/ 正则代表的含义 数字 0-9 ,等价于 \d
/[^0-9]/ 正则代表的含义 非数字 0-9 ,等价于 \D
/[^a-z]/ 表示字母 a-z
/[0-9a-zA-Z]/ 等价于 \w
var reg = /^(abc){2}$/
console.log(reg.test('abc')) // false
console.log(reg.test('abcabc')) // true
console.log(reg.test('abcqwe')) // false
var reg = /a|b/
console.log(reg.test('a')) // true
console.log(reg.test('b')) // true
console.log(reg.test('c')) // false
var reg = /^[abcd]$/
//字符串中,包含a b c d 任意一个即可
console.log(reg.test('a')) //true
console.log(reg.test('b')) //true
console.log(reg.test('c')) //true
console.log(reg.test('d')) //true
console.log(reg.test('abcd')) //false
var reg = /^[^abcd]$/
console.log(reg.test('a')) //false
console.log(reg.test('c')) //false
console.log(reg.test('w')) //true
7. 元字符或的分界线在哪里(面试题)
或的分界线为 小括号 或者 正则的边界
// var reg = /^abc|def$/
/**
* 分析:
* /^abc|def$/
*
* ^abc 或者 def$
*/
console.log(reg.test('abc12345678')) // true
console.log(reg.test('12345678def')) // true
console.log(reg.test('1234abcdef5678')) // false
var reg = /^ab(c|d)ef$/
/**
* 分析
* ^ab c ef$
* ^ab d ef$
*/
console.log(reg.test('abcef')) // true
console.log(reg.test('abdef')) // true
console.log(reg.test('qwef')) // false
console.log(reg.test('abqwe')) // false
8. 正则的重复元字符
符号: \数字
- \1 \2 \3
- 含义: 表示 重复 第 n 个小括号的内容, 并且 要求和小括号的内容完全一致
var reg = /^(abc|def)\1$/
/**
* \1 重复前边第一个小括号的内容, 小括号内如果是 'abc' 那么 \1 的值也需要是 'abc'
*/
console.log(reg.test('abcabc')) // true
console.log(reg.test('defdef')) // true
console.log(reg.test('abcdef')) // false
console.log(reg.test('defabc')) // false
/**
* 要求 字符串是 span 标签 或者 p标签
*/
var reg = /<(span|p)><\/\1>/
/**
* 流程:
* 1. var reg = /<span></span>/
* !!! 因为 span 的结束标签前有一个 / JS会把它识别为正则的结束, 所以需要加一个转义符
*
* 2. var reg = /<span><\/span>/
* !!! 因为 span 或者 p 标签都可以, 所以 需要将 span 标签开头添加一个 元字符或
*
* 3. var reg = /<(span|p)><\/span>/
* !!! 因为 结束标签的文本一定和开始标签相同, 所以可以在结束标签后 写一个 \1 表示重复第一个小括号的内容
*
* 4. var reg = /<(span|p)><\/\1>/
*/
console.log(reg.test('<span></span>'))
console.log(reg.test('<p></p>'))
console.log(reg.test('<div></div>'))
9. 正则的标识符
书写在正则外面, 用来描述整个正则表达式
- i
- 表示忽略大小写
- g
- 表示 全局
- 欠着
var reg = /^[abcd]$/i
console.log(reg.test('a')) //true
console.log(reg.test('A')) //true
console.log(reg.test('w')) //false
10. 正则的两大特性 (面试常问)
- 懒惰
- 每次捕获 都是在 下标[0] 的位置开始捕获
- 解决: 在正则后添加全局标识符 g
- 贪婪
- 每次捕获内容的时候, 尽可能的多去捕获内容
- 解决: 使用非贪婪限定符 (在原有的限定符后添加一个?) 贪婪限定符
? {n,} {n,m}
非贪婪限定符 *? {n,}?
var str = '<div class="box" id="id_box"><span></span></div>'
// 贪婪捕获
var reg1 = /<div.*>/
console.log(reg1.exec(str)[0])
// 非贪婪捕获
var reg2 = /<div.*?>/
console.log(reg2.exec(str)[0])
11. 案例练习
案例需求:
将 字符串内 所有满足正则规则的 片段 全部捕获出来, 放到一个数组内
var reg = /\d{3}/g
var str = 'qwe123asd456zxc789'
var arr = []
var newStr = reg.exec(str) // 数组
while (newStr !== null) {
arr.push(newStr[0])
newStr = reg.exec(str)
}
console.log(arr)
/**
* 分析:
* 首次执行 newStr 是一个数组, 下标0 为 '123'
*
* 满足 while 循环 执行循环内容
* 1. arr.push(newStr[0])
* 2. newStr = reg.exec(str) 此时 newStr 是一个数组, 下标0 为 '456'
*
* 第二次执行 newStr 还是一个数组, 下标0 为 '456'
* 满足 while 循环 执行循环内容
* 1. arr.push(newStr[0])
* 2. newStr = reg.exec(str) 此时 newStr 是一个数组, 下标0 为 '789'
*
* 第三次执行 newStr 还是一个数组, 下标0 为 '789'
* 满足 while 循环 执行循环内容
* 1. arr.push(newStr[0])
* 2. newStr = reg.exec(str) 此时 已经没有符合正则规则的内容 所以捕获的值为 null
*
* 第四此执行 newStr 是一个 null
*/
/**
* ['123', '456', '789']
*/
12. 正则创建方式的区别
书写标识符
- 字面量的方式, 直接在正则后书写标识符
- 内置构造函数的方式, 需要写在第二个参数中
//1.书写标识符
let reg3 = /abc/i
let reg4 = new RegExp('qwe', 'ig')
//2.书写元字符
let reg1 = /\d\w\s.\./
console.log(reg1)
let reg2 = new RegExp('\\d\\w')
console.log(reg2)
/**
* 在字符串中, 如果 书写了 \ 那么相当于转义符, 将后边的字符转换为 有意义的字符
*
* 但是 转换完成之后, \ 就会自动消失, 那么正则拿到的就是一个 具有特殊含义的 字符 d
*
* 但是又因为 正则中 元字符 必须是 \ + d 结合在一起才是一个元字符, 如果只有一个 d 那么就是一个普通的字母, 没有任何特殊含义
*
*
* 解决方式:
* 在原本的 \ 前再添加一个 \
*
* 第一个 \ 将 第二个 \ 转换为没有任何意义的 普通文本, 最终正则拿到的就是一个 没有特殊含义的 \ + d
* 然后按照正则的规则中, \+d 就是一个元字符, 代表的是数字0-9
*/