1、什么是正则表达式
// 介绍:正则表达式(regular expression)是一个描述字符模式的对象,是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照"给定模式"匹配文本。
2、正则表达式的特点
// 1. 灵活性、逻辑性和功能性非常的强。
// 2. 可以迅速地用极简单的方式达到字符串的复杂控制。
// 3. 对于刚接触的人来说,比较晦涩难懂。比如:/^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$/ 验证邮箱的表达式
// 4. 实际开发,一般都是直接复制写好的正则表达式. 但是要求会使用正则表达式并且根据实际情况修改正则表达式. 比如用户名: /^[a-z0-9_-]{3,16}$/
3、正则表达式的作用
// 正则表通常被用来检索、替换那些符合某个模式(规则)的文本,例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)。此外,正则表达式还常用于过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。
4、正则表达式的创建
// vscode可以安装any-rule插件, 该插件提供了一些常用的正则表示式 安装完成以后 按ctrl+shift+p快捷键以后, 找到正则大全 可以根据需求改一些常用正则表达式
4.1 通过调用RegExp对象的构造函数创建
// var 变量名 = new RegExp("正则表达式" [,"匹配模式"] );
❤4.2 利用字面量创建(推荐) 正则表达式
// var 变量名 = /正则表达式/[匹配模式];
// 注意: 匹配模式可以省略不写
5、测试正则表达式 test()方法
// 正则对象的test()方法,用于检测字符串是否符合该规则(匹配),该对象会返回 true 或 false,其参数是被测试字符串。
// test() 方法执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 true 或 false。
// 语法:
// regexObj.test(str)
// 说明:
// 1. regexObj 正则表达式
// 2. str 测试字符串
6、正则表达式的组成
// 一个正则表达式可以由简单的字符构成,比如 /abc/,也可以是简单字符和特殊字符的组合,比如 /ab*c/ 。其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,如 ^ 、$ 、+、 * 、 ?等。
// 特殊字符非常多,可以参考相关文档:
// 1. jQuery手册正则表达式部分 https://jquery.cuishifeng.cn/regexp.html
// 2. 菜鸟教程 https://www.runoob.com/regexp/regexp-tutorial.html
// 3. 菜鸟教程正则表达式在线测试 https://c.runoob.com/front-end/854/
// MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
6.1 边界符
// 正则表达式中的边界符(位置符)用来提示字符所处的位置,边界符主要有以下两个
// 边界符 说明
// ^ 表示匹配行首的文本(以谁开始)
// $ 表示匹配行尾的文本(以谁结束)
// 注意: 如果 ^和 $ 在一起,表示必须是"精确匹配",表示"只能是这个字符串"
6.2 字符类
// 字符类表示有一系列字符(多个字符)可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号[]内。
// [] 方括号
// [] 方括号,表示有一系列字符可供选择,只要匹配其中一个就可以了
6.3 范围符-
// [-] 方括号内部 范围符-
// 方括号内部加上 - 表示范围
// 可以在中括号里面加一个短横线表示一个范围 ,比如[a-z]表示a到z的26个英文字母任何一个字母,包括a和z
6.4 字符组合
// 方括号内部可以使用字符组合,这里表示包含 a 到 z 的26个英文字母和 1 到 9 的数字都可以
// 举例: /[a-z1-9]/.test('andy') // true
// 取反符^
// [^] 方括号内部 取反符^
6.5 量词符
// 量词符用来设定某个模式出现的次数。
// 注意: 没有小括号的情况下, 量词符是修饰前一个字符出现的次数
// 量词 说明
// * 重复0次或更多次
// + 重复1次或更多次
// ? 重复0次或1次
// {n} 重复n次
// {n,} 重复n次或更多次
// {n,m} 重复n到m次
// 组匹配,分组,使用()表示
// 功能: 把多个原子,组在一起,成一个大原子
// 区别:
// /^abc{2}$/ 代表c这个字符重复2次
// /^(abc){2}$/ 代表abc这个整体进行重复2次
// 括号总结
// 1.中括号 字符集合 匹配方括号中的任意字符
// 2.大括号 量词符 里面表示重复次数
// 3.小括号 组匹配 可以让多个小原子组成一个大原子
// 我们还可以在线测试正则表达式
// regexper(外国网站) https://regexper.com/
6.6 预定义类
// 预定义类指的是某些常见模式的简写方式
// 参考文档: https://jquery.cuishifeng.cn/regexp.html
// \w 匹配包括下划线的任何单词字符。等价于"[A-Za-z0-9_]"
// \W 匹配任何非单词字符。等价于"[^A-Za-z0-9_]"
// \d 匹配一个数字字符。等价于[0-9]
// \D 匹配一个非数字字符。等价于[^0-9]
// \s 表示一个空白字符(空格,tab制表符,换页符\f,换行符\n,回车符\r 等)
// vscode直接用tab键按出来的可能是多个空格组成符号,不是真正制表符
// \S 表示一个非空白字符
\b 表示单词边界
以下内容可以当作单词边界:
-
空格
-
某句的开始
-
某句的结束
// 字符串对象的replace方法第一个参数可以写正则表达式, 表示对匹配到的内容,进行替换,默认只能替换一次
// 如果要全部替换,我们可以使用匹配模式g, g表示global全局匹配
// \B表示非单词边界
// . 表示除换行符(\n)回车符(\r)外的其它单个字符
// 注意: .只是表示表达能力比较强,可以表示多种字符。但一个原子在数量上,还是只能表示一个字符。
6.7 匹配模式
// 匹配模式也叫修饰符:表示正则匹配的附加规则,放在正则模式的最尾部。
// 修饰符可以单个使用,也可以多个一起组合使用, 多个修饰符组合使用时,不分顺序。
// 参考文档: https://www.runoob.com/regexp/regexp-flags.html
// 在正则表达式中,匹配模式常用的有两种形式:
// g :global缩写,代表全局匹配,匹配出所有满足条件的结果,不加g第一次匹配成功后,正则对象就停止向下匹配;
// i :ignore缩写,代表忽略英文字母大小写,匹配时,会自动忽略字符串的英文字母大小写
// gi:全局匹配 + 忽略大小写
// m: multiline 表示多行匹配(将开始和结束字符(^ and $)视为在多行上工作。换句话说,匹配每一行的开头或结尾each line (由\n或者\r 分隔),而不仅仅是整个输入字符串的开头或结尾。)
// 默认情况下,没有设置多行匹配的时候, 会把所有字符串内容当前一整行匹配
// replace的第一个参数可以是字符串
// replace的第一个参数也允许使用正则表达式
// 匹配模式组合使用 多个修饰符一起使用,不分顺序
7、 正则对象相关方法
// 正则对象.test(str) : 判断字符串中是否具有指定模式的字符串,返回结果是一个布尔类型的值;
// 正则对象.exec(str) : 返回字符串中指定模式的子串,一次只能获取一个与之匹配的结果;
// 格式:
// 返回值 = 正则.exec(目标字符串)
// 功能: 匹配。在目标字符串中,找出符合正则表达式要求的字符串。
// 返回值:如果能够匹配某个字符串,则返回值是一个数组。其中:
// 第一个是匹配成功的字符串;
// 第二个index,表示在哪里匹配到的。
// 第三个input,表示目标字符串
// 如果不能匹配,则返回值是null
// 注意: 一次exec只能得到一个匹配成功的结果 ,如果要全部匹配出来,则需要调用多次exec
// 注意: 如果要全部结果匹配出来, 全局匹配模式g不能少! 否则exec每次只能得到字符串中第一次匹配到的那个结果
// 有一个问题,我们事先并不知道,这个匹配会成功多少次?所以我不能用for循环去执行匹配。
var res;
while (res = reg.exec(str)) {
console.log(res);
}
8、String对象跟正则相关方法
// (1) 字符串对象.search(reg) :与indexOf非常类似,返回指定模式的子串在字符串"首次"出现的位置
// ❤❤❤(2) 字符串对象.match(reg) :以数组的形式返回指定模式的字符串,可以返回所有匹配的结果
// 注意: match(reg)方法如果不是全局匹配,匹配出来的效果跟正则对象的exec方法一样
// ❤❤❤(3) 字符串对象.replace(reg,"替换后的字符") :把指定模式的子串进行替换操作
// 字符串对象.replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。
// (4) 字符串对象.split(reg) :以指定模式分割字符串,返回结果为数组
// indexOf参数不建议写正则表达式 不管能否找到,都是返回-1
// (3) 字符串对象.replace(reg,"替换后的字符")
// replace()基本用法,第二个参数是字符串
// stringObject.replace(regexp或string,replacement)
// 1. 第一个参数: 被替换的字符串 或者 正则表达式
// 2. 第二个参数: 替换为的字符串
// 3. 返回值是一个替换完毕的新字符串
// replace()高级用法,第二个参数是function
// 每次找到一次目标,就会调用一次function(){}匿名函数,把目标替换成函数中的return值;
// 目标可以通过匿名函数中的arguments关键字查看
9、反向引用(组匹配)
// 概念
// 在做匹配时,如果正则表达式中有小括号,则它会把小括号中所匹配到的文本都存储在一个特殊的地方, 以备以后使用。
// 这些存储在分组中的特殊值被称为反向引用。
9.1 如何使用反向引用的结果:
// 使用反向引用的结果第一种方法:
RegExp构造函数的静态属性
// RegExp.$n 获取第n个()中匹配的内容,n是从1开始的自然数
// 注意: "只有执行过正则相关方法",才可以使用RegExp.$n的方式得到反向引用的结果
// ❤❤❤使用反向引用的结果第二种方法:
直接在定义分组的正则表达式中包含反向引用。通过特殊的转义序列 \1,\2... 来调用。
// 使用反向引用的结果第三种方法:
在匹配成功的数组中,通过下标去访问。
9.2 反向引用与replace结合使用
javascript
// 目标字符串: "生日是:1991-10-11。生日是:1998-11-12。生日是:1990-1-10。生日是:1990/09/11。生日是:1980-01-13。";
// 把生日中的格式调整一下, 1990-01-31(年-月-日) ===> 31-01-1990(日-月-年)
var str = "生日是:1991-10-11。生日是:1998/11/12。生日是:1990-1-10。生日是:1990/09/11。生日是:1980-01-13。生日是: 2022-7/14"; var reg = /(\d{4})([-/])(\d{1,2})\2(\d{2})/g; var newStr = str.replace(reg, function (result, year, $2, month, day) { return day + "-" + month + "-" + year; }); console.log("newStr=>", newStr);
10、或者的用法
用|符号表示或者的意思
// 语法:
// x|y 匹配x或y
11、转义字符
// 因为在正则表达式中 . + * ? 等是属于正则表达式的一部分,但是我们在匹配时,字符串中也需要匹配这些特殊字符,所以,我们必须使用 反斜杠\ 对某些特殊字符进行转义;
// 需要转义的字符:
// 点号.
// 小括号()
// 中括号[]
// 左斜杠 /
// 右斜杠\
// 选择匹配符 |
// ...
12、取消反向引用(非捕获组)
// 介绍:(?:x)称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。
// 概念:非捕获组的作用请考虑这样一个场景,假定需要匹配foo或者foofoo,正则表达式就应该写成/(foo){1, 2}/,但是这样会占用一个组匹配。这时,就可以使用非捕获组,将正则表达式改为/(?:foo){1, 2}/,它的作用与前一个正则是一样的,但是不会单独输出括号内部的内容。
// 引用分组会需要额外的空间存储。当我们只是需要分组(把小原子组成大原子)而不需要引用时,就可以手动取消这个引用。
// 原子就是单个字符 比如 /abc{2}/ => /(abc){2}/
// 做法是: 在()里面的前面加一个 ?: 即可
13、贪婪匹配与惰性匹配
// 对QQ号码进行校验要求5~13位,不能以0开头,只能是数字
// 我们会发现以上代码运行结果中,默认优先配到 13 位,在对后面的进行匹配;为什么不是优先匹配 5 位后,在对后面的进行匹配呢?
// 因为在正则表达式中,默认情况下,能匹配多的就不匹配少的,我们把这种匹配模式就称之为 贪婪匹配,也叫做 贪婪模式所有的正则表达式,默认情况下采用的都是贪婪匹配原则。
// 如果在量词符的后面添加一个问号? 那我们的贪婪匹配原则就会转化为非贪婪匹配原则,优先匹配少的,也叫惰性匹配;