在代码中我们常常能看到regexp、reg、re或者诸多类似的变量名,大多都是表示的是正则表达式的规则
使用正则表达式我们可以来完成内容的检索和文本的替换等等,也可以用来验证一个字符串是否符合你要的规则。
1、如何创建正则表达式
方式一:
var reg = /匹配模式/匹配标志
var reg = /\d/gi
方式二:
var reg = new RegExp("匹配模式","匹配标志")
var reg = new RegExp("\\d","gi")
//如果是使用new实例化在匹配模式中想\d这样的字符需要转义
2、修饰符
g:表示全局模式,应用所有字符串,不在第一个匹配之后立即停止。所有的正则表达式都有一个lastIndex属性用于记录上一次匹配结束的位置,如果不是全局匹配,那么lastIndex的值始终为0,匹配过一次之后将会停止匹配。
设置了g之后那么就可以对字符串进行多次匹配,每次匹配的时候都使用当前的lastIndex作为字符串开始匹配的起始位置。
i:忽略大小写
m:表示多行模式,到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项
s: 默认情况下的圆点 . 是 匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。
var regex = /abc/g;
var str = '123#abc';
console.log(regex.lastIndex); // 0
console.log(regex.test(str)); // true
console.log(regex.lastIndex); // 7
console.log(regex.test(str)); // false
console.log(regex.lastIndex); // 0
console.log(regex.test(str)); // true
console.log(regex.lastIndex); // 7
console.log(regex.test(str)); // false
3、使用正则表达式
1、RegExp类
/*
基本语法:RegExp.test(str)
作用:检测字符串是否满足该正则表达式,匹配成功返回true,反之返回false
*/
const reg = /^(hello)/gi
reg.test('hello world') // true
reg.test('world hello') // false
/*
基本语法:RegExp.compile(pattern[,flag])
作用:重新编译指定的正则表达式,编译之后正则表达式执行速度会提高,如果正则表达式多次被调用,那么调用compile方法可以有效的提高代码的执行速度,如果该正则表达式只能被使用一次,则不会有明显的效果。
*/
var reg = new RegExp("13[4-9](//d){8}", "g")
reg.compile("13[0-3](//d){8}", "g"); // 把reg的正则修改为传入的正则
/*
基本语法:RegExp.exec(str)
如果匹配成功返回一个数组。返回的数组以匹配值作为第一项,随后每一项就是在这个匹配值中的捕获组。如果没有匹配成功,则返回null。正则表达式中()为捕获组
*/
var reg = new RegExp("(abc).*(xy)")
let result = reg.exec("111abc111xy")
console.log(result) // 输出['abc111xy', 'abc', 'xy', index: 3, input: '111abc111xy']
2、String类
字符串的一些方法中可以使用正则表达式
var str = "abc1233";
//定义正则表达式规则
var reg = /\d/gi;
//匹配符合匹配模式的字符串出现的位置,没有匹配到则返回-1
str.search(reg);
//以数组形式返回匹配模式的字符串,没有匹配到则返回null
str.match(reg)
//使用指定的内容替换匹配模式的字符串
str.replace(reg, "content")
//使用匹配模式的字符串做为分隔符对字符串进行分割,返回数组
str.split(reg)
4、规则
4.1、元字符
表达式 | 作用 |
\d | 任意一个数字,0~9 中的任意一个 |
\D | 匹配一个非数字字符。等价于 [ ^0-9 ] |
\w | 任意一个字母或数字或下划线,也就是 AZ,az,0~9,_ 中任意一个 |
\W | 匹配非字母、数字、下划线。等价于 [ ^A-Za-z0-9_ ] |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v] |
\S | 匹配任何非空白字符。等价于 [ ^ \f\n\r\t\v] |
. | 小数点可以匹配除了换行符(\n)以外的任意一个字符 |
^ | 与字符串开始的地方匹配,不匹配任何字符 |
$ | 与字符串结束的地方匹配,不匹配任何字符 |
\b | 匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符 |
\B | 非单词边界匹配 |
[ab5@] | 匹配 “a” 或 “b” 或 “5” 或 “@” |
[^abc] | 匹配 “a”,“b”,“c” 之外的任意一个字符 |
[f-k] | 匹配 “f”~“k” 之间的任意一个字母 |
[^A-F0-3] | 匹配 “A”“F”,"0"“3” 之外的任意一个字符 |
{n} | 表达式重复n次,比如:“\w{2}” 相当于 “\w\w”; “a{5}” 相当于 “aaaaa” |
{m,n} | 表达式至少重复m次,最多重复n次,比如: "ba{1,3}"可以匹配 “ba"或"baa"或"baaa” |
{m,} | 表达式至少重复m次,比如: “\w\d{2,}“可以匹配 “a12”,”_456”,“M12344”… |
? | 匹配表达式0次或者1次,相当于 {0,1},比如: "a[cd]?"可以匹配 “a”,“ac”,“ad” |
+ | 表达式至少出现1次,相当于 {1,},比如: "a+b"可以匹配 “ab”,“aab”,“aaab”… |
* | 表达式不出现或出现任意次,相当于 {0,},比如: “^*b"可以匹配 “b”,”^^^b"… |
4.2、贪婪模式
通过在*、+或 ? 后面放置 ? , 该表达式从"贪婪"表达式转换为"非贪婪"表达式或者最小匹配。
// 贪婪模式
var reg = /<.*>/
let result = reg.exec("<h1>标题</h1>")
console.log(result) // 匹配到的是"<h1>标题</h1>"
// 非贪婪模式
var reg = /<.*?>/
let result = reg.exec("<h1>标题</h1>")
console.log(result) // 匹配到的是"<h1>"
4.3、捕获组(子表达式)和反向引用
在正则匹配模式中,括号中的内容就是捕获组
捕获组匹配到的内容会被系统捕获至系统的缓冲区中
捕获之后在匹配模式中使用\n(n为数字)来引用系统第n号缓冲区的内容称为反向引用
//例1:匹配html标签中的内容
var str = 'abxzcvcb<div>商品</div>fdgdfbvn<p>价格</p>vbcn'
var reg = /<(\w+)>.+<\/\1>/gi
//查找连续的相同的四数字,如:1111
var reg=/(\d)\1\1\1/gi;
//查找数字,如:1221,3443
var reg=/(\d)(\d)\2\1/gi;
//例2:结巴程序
var str='我我我...我我...是是...一一个个个个...帅帅帅帅帅帅帅帅帅帅哥!';
var reg=/\./gi;
//将所有.替换成空
str=str.replace(reg,'');
alert(str);
//我我我我是是是是一个个个
reg=/(.)\1+/gi;
//使用1号缓冲区内容替换重复的内容
str=str.replace(reg,'$1');
alert(str);
一般情况,后面的内容要求与前面的一致,就会用到子表达式、捕获和反向引用
4.4、限定符
限定符可以指定正则表达式的一个部分需要出现多少次才能满足匹配
*:匹配前面的内容零次或多次
+:匹配前面的内容一次或多次
?:匹配前面的内容零次或一次
{n}:匹配确定的n次
{n,}:至少匹配n次
{n,m}:最少匹配n次且最多匹配m次
4.5、字符匹配符
[a-z] :表示a-z任意一个字符
[A-Z] :表示A-Z任意一个字符
[0-9] :表示0-9任意一个数字
[0-9a-z] :表示0-9 a-z任意一个字符
[0-9a-zA-Z] :表示0-9 a-z A-Z任意一个字符
[abcd] :表示a 或b 或c 或 d
[1234] :表示 1 或2 或3 或 4
[^a-z]:表示匹配除了a-z之间任意一个字符
[^0-9] :表示匹配除了0-9之间任意一个字符
[^abcd] :表示匹配除a b c d 之外的任意一个字符
\d :匹配一个数字字符。[0-9]
\D :匹配一个非数字字符。[^0-9]
\w :匹配包括下划线的任何单词字符。[0-9a-zA-Z_]
\W :匹配任何非单词字符。[^\w]
\s :匹配任何空白字符 空格、制表符、换行符
\S :匹配任何非空白字符。
. :匹配除 “\n” 之外的任何单个字符 如果想匹配任意字符 [.\n]
4.6、定位符
^ :匹配输入字符串的开始位置
$ :匹配输入字符串的结束位置
\b :匹配一个单词边界
\B :匹配非单词边界
4.7、需要转义的字符
(
)
[
]
{
}
\
.
/
*
+
?
^
$
4.8、|
可以用来匹配多个规则
var str = 'hello Jack!hello Mike!';
var reg = /hello (Jack|Mike)/gi
4.9、非捕获元
?: 、?= 、?<= 、?! 、?<!
非捕获元 | 作用 |
(?:pattern) | 匹配 pattern 但不获取匹配结果。 |
(?=pattern) | 正向肯定预查(look ahead positive assert)。这是一个非获取匹配。 |
(?!pattern) | 正向否定预查(negative assert)。这是一个非获取匹配。 |
(?<=pattern) | 反向肯定预查,与正向肯定预查(?=pattern)类似,只是方向相反。这是一个非获取匹配。 |
(?<!pattern) | 反向否定预查,与正向否定预查(?!pattern)类似,只是方向相反。这是一个非获取匹配。 |
var str = 'a1b2c3d4'
// 正向肯定 (匹配右边是1或者2的\w)
var reg = /\w(?=1|2)/g
console.log(str.match(reg)) // 共找到两处匹配:a, b
// 正向否定 (匹配右边不是1或者2的\w)
var reg = /\w(?!1|2)/g
console.log(str.match(reg)) // 共找到6处匹配:1, 2, c, 3, d, 4
// 反向肯定 (匹配左边是1或者2的\w)
var reg = /(?<=1|2)\w/g
console.log(str.match(reg)) // 共找到2处匹配:b, c
// 反向否定 (匹配左边不是1或者2的\w)
var reg = /(?<!1|2)\w/g
console.log(str.match(reg)) // 共找到6处匹配:a, 1, 2, 3, d, 4
5、常用正则表达式
名称 | 正则表达式 |
用户名 | /^[a-z0-9_-]{3,16}$/ |
密码 | /^[a-z0-9_-]{6,18}$/ |
十六进制值 | /^#?([a-f0-9]{6} |
电子邮箱 | /^([a-z0-9_.-]+)@([\da-z.-]+).([a-z.]{2,6})$/ |
HTML标签 | /^<([a-z]+)([^<]+)*(?:>(.*)</\1> |
Unicode编码中的汉字范围 | /^[\u2E80-\u9FFF]+$/ |
手机号 码 | /^(13[09]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/ |
身份证号 | /^\d{15}|\d{18}$/ |
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线) | /^[a-zA-Z]\w{5,17}$/ |
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间) | /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$/ |
IP地址 | /\d+\.\d+\.\d+\.\d+/ |