正则表达式
一、作用
用来匹配符合某种规则的字符串
案例
- 检索字符串中符合某种规则多个子字符串
- 判断用户的输入是否符合某种规则
- 替换字符串中符合某种规则的文本
- 用户的输入是不是合法的手机号
- 用户的输入是不是合法的邮箱
- 用户的输入是不是合法的用户名
二、创建方式
1、字面量方式创建
简单、直观,最常用
let reg = /+86\d{11} /g // let reg = / /
2、构造函数方式创建
麻烦,但正则规则可通过字符串拼接,有些场景不得不用
let reg = new RegExp('+86\d{11}', 'g')
最后的g代表全局,还有几个修饰符
g:global,全文搜索,不添加的话搜索到第一个结果停止搜索
i:ingore case,忽略大小写,(默认不写的情况下大小写敏感 )
m:multiple lines,多行搜索
三、简单用法
3.1、正则的方法
let reg = /+86\d{11}/
reg.test('+8613012344321')
3.2、字符串方法
let str = 'hello1 jirengu, hello2 world'
str.search(/hello\d/) // 0
str.match(/hello\d/g) //['hello1', 'hello2']
str.replace(/hello\d/g, 'hi') // 'hi jirengu, hi world'
str.split(/\s/) //["hello", "jirengu,", "hello", "world"]
3.3、专用字符
具有特殊意义的字符
( [ { \ ^ $ | ) ? * + .
如果要匹配这些特殊字符,需要转义\
四、字符匹配
4.1、字符匹配
let reg = /jirengu/
reg.test('hello jirengu') // true
4.2、范围匹配
[abcd] 匹配一个字符,是a b c d中的任意一个
[0-9] 匹配一个是0到9的数字
[a-zA-Z]匹配一个不限制大小写的字母
[^abc] 表示一个不是字符a或b或c的字符
let reg = /不要[89][89][67]/
reg.test('我们不要996') //true
reg.test('我们不要897') //true
reg.test('我们要965') //flase
4.3、预定义匹配
预定义匹配
. 等价于 [^\r\n],匹配一个除回车和换行以为的任意字符
\d 等价于[0-9],匹配一个数字字符
\D 等价于[^0-9], 匹配一个非数字字符
\s 等价于[空格\t\n\r\v\f],匹配一个空白字符
\S 等价于[^空格\t\n\r\v\f],匹配一个非空白字符
\w 等价于[a-zA-Z_0-9],匹配一个字母、数字、下划线
\W 等价于[^a-zA-Z_0-9],匹配一个非单词字符
五、量词
匹配 0个到多个
?前面的字符出现0次或者1次
+ 前面的字符出现1次或者多次
* 前面的字符出现0次或者多次
{n}前面的字符出现n次
{n,m} 前面的字符出现n到m次
{n,}前面的字符出现至少n次
let str1 = 'http://jirengu.com';
/https?:\/\/.+/.test(str1) // true
/https+:\/\/.+/.test(str1) // false
/https*:\/\/.+/.test(str1) // true
let str2 = 'https://jirengu.com';
/https?:\/\/.+/.test(str2) //true
/https+:\/\/.+/.test(str2) //true
/https*:\/\/.+/.test(str2) //true
let str3 = 'httpssssss://jirengu.com';
/https?:\/\/.+/.test(str3) //false
/https+:\/\/.+/.test(str3) //true
/https*:\/\/.+/.test(str3) //tru
边界
以...开头或者以...结尾
/^xyz/ 以xyz开头
/abc$/ 以abc结尾
/\babc\b/ 匹配是单词的abc(左右两侧是字符串开头、 结尾、中横线、空格)
/\Babc\B/ 匹配不是单词的abc
var str = 'hello1 world hello2 123456 ruoyu hello3'
str.match(/hello\d/g) // ["hello1", "hello2", "hello3"]
str.match(/^hello\d/g) // ["hello1"]
str.match(/hello\d$/g) // ["hello3"]
var str2 = 'hello1 whello9orld hello2 12-hello8-3456 jirengu ruoyu hello3'
str2.match(/\bhello\d\b/g) // ["hello1", "hello2", "hello8","hello3"]
// 注意-也用于区分单词边界
七、案例
7.1、匹配手机号
判断用户的输入是否符合手机号规则
规则:以1开头长度为11的数字
let reg = /^1\d{10}$/ reg.test(' 13189890989') // false
reg.test('a13189890989b') // false
reg.test('13189890989') // true
reg.test('1318989098910') // false
验证是为了防止用户误操作,不是越严格越好
7.2、匹配邮箱
判断用户的输入是否符合邮箱规则
规则:字符串中间包含一个@,@后面包含个.
let reg = /^[^@\s]+@[^@\s]+\.[^@\s]+$/
reg.test('hr@jirengu.com) // true
reg.test('admin@jirengu.中国') // true
reg.test('abc@cdd@jirengu.cn') // true
reg.test('abc@j rengu.com') // fasle
7.3、匹配用户名
判断用户的输入是否是合法用户名
规则:合法用户名至少8位至多15位,包含大写、小写、 数字、下划线至少两种
function validUsername(rawInput) {
//如果 不 满足 全部为字母数字下划线且长度为8~15 返回false
if(!/^\w{8,15}$/.test(rawInput)) return false
// 如果只包含一种 返回false
if(/(^[a-z]+$)|(^[A-Z]+$)|(^[0-9]+$)|(^\d+$)|(^_+$)/.test(rawInput))
return false
return true
}
八、贪婪模式与非贪婪模式
8.1、贪婪模式
问题
'123456789'.match(/\d{3,5}/g) 的结果是什么?是 ['123', '456', '789'] 还是 ['12345', '6789'] ?
解答
ü 默认是贪婪模式,即尽可能多的匹配。如果想使用非贪 婪模式,可以再量词后加 ? 即可 ü '123456789'.match(/\d{3,5}?/g);
分组
把一些字符作为一个整体
//匹配 hungerrr ,而不是 hungerhungerhunger
/hunger{3}/
//把hunger作为一个整体,匹配 hungerhungerhunger
/(hunger){3}/
//匹配 “hello world” 和 “hi world”
/(hello)|(hi) wolrd/
//$1代表正则里分组匹配的内容,输出 “hi8 world, hi6 jirengu”
"hello8 world, hello6 jirengu".replace(/hello(\d)/g, 'hi$1')
<div>hello this is div</div>.replace(/(<\ /?)div(>)/g,'$1span$2')
补充:
.+ 只要不是回车跟换行都行,一次或多次
汇总方法
exec
一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。
test
一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。
match
一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。
matchAll
一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。
search
一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。
replace
一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。
split
一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。