正则表达式
正则表达式是国际标准,跨越语言
正则表达式是一个规则,用于验证字符串。
基础
- 字面量匹配
规则中直接书写字面量字符
特殊字符
. 匹配除换行符 \n 之外的所有单字符。要匹配 . ,请使用 \. ...a... 释义 匹配a前和a后都必须要有3个字符的
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。
^abc… 释义 匹配输入字符串的开始位置为abc且后面接有3个字符 注意只匹配开始位置的其他位置匹配不成功
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 $。
^abc…& 释义:匹配输入字符串的开始位置为abc且后面接有3个字符后就结束 (限定为6位数,多一位就不在匹配)
? 匹配前面的一次或者0次
3. 转义符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
\s 匹配一个空白字符
\S 匹配一个除空白字符以外的所有字符
\b 匹配一个字符串的边界 (字符串开始和结束都是边界 空格 换行 制表符都是边界)
\B 非单词边界匹配
\d 匹配一个数字字符 [0~9] 例:^1\d\d\d\d\d\d\d\d\d\d$ 以1开头的十一位数的号码
\D 匹配一非个数字字符
\w 匹配字母、数字、下划线。等价于’[A-Za-z0-9_]’
\W 匹配非字母、数字、下划线。
\u Unicode 字符转换匹配 \u4f60\u771f\u68d2=你真棒
4. 字符集
[字符范围] 分别匹配字符范围内的一个字符
[^0-9] 释义:匹配除0到9之间以外的字符 =\D*
匹配所有字符:
[\d\D]+ 释义:匹配所有数字字符和非数字字符 至少1个
[\s\S]+
[a-z] [a-zA-Z] [0-9] [A-Za-z0-9_]范围可以随意组合
匹配中文: ```[\u4e00-\u9FA5]``` 汉字unicode编码范围
5. 量词
**指定是(前面)的规则出现的次数** 量词前最近的
单纯匹配本身时例如 + 时需要在其前面 加一个 \ 其他符号同理
- 匹配前面的子表达式零次或多次
- 至少匹配一个或者多个 例:\d+ 释义:至少匹配到一个数字
? 匹配零个或者1个
{n}: 匹配n个
{n,}: 匹配>=n个
{n,m}: 匹配n-m个
例1:匹配6-16位的密码 ^[0-9a-zA-Z]{6,16}$ 释义:匹配范围[0到9 a到z A到Z]6到16位数的字符
例2: 匹配2到6位的中文名字 ^[\u4e00-\u9FA5]{2,6}$
- 或者
多个规则之间,适用或者|
,表示多个规则任选其一
JS中的应用
js中,正则表达式表现为一个对象,该对象是通过构造函数RegExp
创建正则对象
- 字面量模式
var reg1 = /^-?\d+(\.0+)?$/;
- 构造函数模式
var reg2 = new RegExp("^-?\d+(\.0+)?$")
- 直接调用
RegExp("^-?\d+(\.0+)?$");
注意构造函数模式和直接调用是两种不同的创建方式区别:当二者不是直接书写的正则 而是调用的正则构造函数创建的是一个新地址,而直接调用的使用的还是原来的地址
参数 这三者默认是关闭的
开启.书写位置正则后面 //g、i、m
g 全局匹配 找到所有匹配的
i 忽略大小写
m 多行匹配 匹配每一行的开始和结束(^和$)
正则实例成员
global 是否开启了全局搜索 只读属性
ignoreCase 是否开启了忽略了大小写
multiline 是否开启了多行匹配
source 目前规则 得到当前正则字符串
test方法:验证某个字符串是否满足规则
test()函数 判断一个字符串是否匹配 并且在全局匹配模式下影响下一次匹配的位置
结论:开启了全局匹配情况下 第一次匹配成功后索引号会停留在上一次匹配成功的字符上
当连续进行下一次匹配时会从上一次匹配成功结束的索引开始匹配后面的字符,
后面没有可匹配的那就判断为false 在下一次匹配时 重头开始匹配。
没开启全局匹配不会记录索引每次都是重新匹配并只匹配一个.exec方法:execute,执行匹配,得到匹配结果。
正则表达式,默认情况下,适用贪婪模式
在量词后,加上?,表示进入非贪婪模式(把?当为量词时含义是匹配0次或1次 把?写于量词后表示非贪婪模式)
字符串对象中的正则方法
- split 用于把一个字符串分割成字符串数组 第二个参数设定分割数量,默认全分割
- replace 替换与正则表达式匹配的字符 参数一为正则表达式 参数二为替换数据同时也可以写函数
- search 在给定字符串中搜索匹配项,并返回在字符串中找到字符的索引号永远是只找第一匹配的,全局非全局下作用相同
- match 对给定字符串执行匹配并返回匹配结果
进阶
捕获组
(1): 用小括号包裹的部分叫做捕获组,捕获组会出现在匹配结果中 每一个小括号为一个捕获组 嵌套根据实际情况看
在正则表达式中,使用某个捕获组,使用方法:\捕获组编号
(2):捕获组可以命名,叫做具名捕获组(命名捕获组) 在小括号中前面写入 ?<命名>
var p = "2020-6-26,2020-5-1,2020-11-2,2020-11-15";
var regs = /(?<year>\d{4})-(?<month>\d{1,2})-(?<day>\d{1,2})/g;
while (result = regs.exec(p)) {
// console.log(result);
// 0--是整个捕获组 捕获组1 捕获组2 捕获组3
console.log(result.groups);
console.log(result[0], result.groups.year, result.groups.month, result.groups.day);
}
// 下面为输出释义
/*
0: "2ah" 这里是所有匹配值
1: "2a" 这里是小括号捕获组
groups: 记录命名的捕获组 叫做 (具名捕获组)
*/
(3):非捕获组 捕获组是默认是开启的 会占用资源浪费执行效率 关闭捕获方法:在小括号中前面写入 ?:
// var p = "2020-6-26,2020-5-1,2020-11-2,2020-11-15";
// // 年不会被捕获了 只会匹配输出
// var regs = /(?:\d{4})-(?<month>\d{1,2})-(?<day>\d{1,2})/g;
// while (result = regs.exec(p)) {
// // 0--是整个捕获组 捕获组1 捕获组2 捕获组3
// console.log(result[0], result.groups.year, result.groups.month, result.groups.day);
// console.log(result.groups);
// }
了解
// 方法replace()--替换 也可以使用捕获组 例题:把一个日期中的横杠换成斜杠 但两个日期间的符号不改变
var p = "2020-6-26,-2020-5-1,2020-11-2,-2020-11-15";
var regs = /(\d{4})-(\d{1,2})-(\d{1,2})/g;
// 方法1. function 1值匹配结果,后面的值表示捕获组
// p = p.replace(regs, function (match, g1, g2, g3) {
// console.log(match, g1, g2, g3);
//
// return `${g1}/${g2}/${g3}`
// });
// 方法2. 使用特殊符号 /$1 表示捕获组1 $1前后添加数据为替换值
p = p.replace(regs, "/$1/$2/$3");
console.log(p);
反向引用
释义:重复正则匹配上一次的匹配结果满足该要求才为匹配项
//例题:
var reg = /(\d{2})\1/; //释义: 匹配两个数字并重复一次的
var s = "1212";
var s2 = "1213"
console.log(reg.test(s)); //true
// console.log(reg.test(s2)); //false
正向断言(预查)
检查某个字符后面的字符是否满足某个规则,该规则不成为匹配结果,并且不称为捕获组
负向断言(预查)
检查某个字符后面的字符是否不满足某个规则,该规则不成为匹配结果,并且不称为捕获组