大部分内容我是从b站上学习的
这是视频连接
let reg =/d+/
let reg=new RegExp("\\d+")
//1.两个斜杠中间包起来的都是元字符(如果正则中要包含某个变量的值,则不能使用字面量的方式创建)
let type = 'hello'
let reg = /^@"+type+"@$/;
reg.test('@hello@')//false
let reg2 = new RegExp("^@" + type + "@$");
reg2.test('@hello@')//true
1.元字符
2.修饰符
let reg = /^\d+$/
let result = reg.test('1141')
//=>result=true
let reg = /\w+\d+$/
let result = reg.test('qe12')
//=>result=true
let reg = /^\d+/
let result = reg.test('1141q1')
//=>result=true
let reg = /\d+$/
let result = reg.test('qwe111')
//=>result=true
let reg=/^18|19/
reg.test('18')
reg.test('29')
reg.test('129')
reg.test('189')
reg.test('1829')
reg.test('829')
reg.test('182')
//=>结果全为true
let reg = /^(18|29)$/
result = reg.test('18')//=>result=true
result = reg.test('29')//=>result=true
result = reg.test('129')//=>result=false
result = reg.test('189')//=>result=false
result = reg.test('1829')//=>result=false
result = reg.test('829')//=>result=false
result = reg.test('182')//=>result=false
let reg=/^[@+]+$/
reg.test('@@') //true
reg.test('@+') //true
let reg=/^[@+]$/
reg.test('@') //true
reg.test('@+')//true
reg.test('@@')//false
reg.test('@+')//false
let reg=/^[\d]+$/
reg.test('d') //false
reg.test('\\') //false
reg.test('9') //true
let reg=/^[\\d]+$/ //这里\将\进行了转义,所有[]内容为\d
reg.test('d') //true
reg.test('\\') //true
reg.test('9') //false
let reg=/^[0-9]+$/
reg.test('0')//true
reg.test('1')//true
reg.test('3')//true
reg.test('8')//true
reg.test('-')//false
let reg=/^[10-29]+$/ //并不能表示10-29的范围,只能表示1,0,2,9,这几个数字和下划线
reg.test('10')//true
reg.test('20')//true
reg.test('13')//false
reg.test('18')//false
reg.test('-')//false
reg.test('1-')//false
reg.test('-2')//false
问号左边是非量词元字符:本身代表量词元字符,出现零到一次
问号左边是量词元字符:取消捕获时候的贪婪性
(?:)z只匹配不捕获 (?:x)称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。非捕获组的作用请考虑这样一个场景,假定需要匹配foo或者foofoo,正则表达式就应该写成/(foo){1, 2}/,但是这样会占用一个组匹配。这时,就可以使用非捕获组,将正则表达式改为/(?:foo){1, 2}/,它的作用与前一个正则是一样的,但是不会单独输出括号内部的内容。
var m = 'abc'.match(/(?:.)b(.)/);
m // ["abc", "c"]
上面代码中的模式,一共使用了两个括号。其中第一个括号是非捕获组,所以最后返回的结果中没有第一个括号,只有第二个括号匹配的内容。下面是用来分解网址的正则表达式。
// 正常匹配
var url = /(http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;
url.exec('http://google.com/');
// ["http://google.com/", "http", "google.com", "/"]
// 非捕获组匹配
var url = /(?:http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;
url.exec('http://google.com/');
// ["http://google.com/", "google.com", "/"]
(?=)正向预查 x(?=y)称为先行断言(Positive look-ahead),x只有在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟着百分号的数字,可以写成/\d+(?=%)/ “先行断言”中,括号里的部分是不会返回的。
var m = 'abc'.match(/b(?=c)/)
m // ["b"]
(?!)负向预查 x(?!y)称为先行否定断言(Negative look-ahead),x只有不在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟的不是百分号的数字,就要写成/\d+(?!%)/。
/\d+(?!\.)/.exec('3.14') // ["14"]
上面代码中,正则表达式指定,只有不在小数点前面的数字才会被匹配,因此返回的结果就是14。“先行否定断言”中,括号里的部分是不会返回的
var m = 'abd'.match(/b(?!c)/)
m // ['b']
规则分析
1. 可能出现+,-号,也有可能不出现
2. 如果只有一位0-9范围内的数字都可以,多位则首位不能为0
3. 小数部分可能有可能没有,如果有则必须为小数点+数字
let reg=/^[+-]?(\d|([1-9]\d+)(\.\d+)?$/
规则分析
1. 数字,字母,下划线
2. 6-16位
function CheckPassword(value) { //以前的方法
if (value.length < 6 || val.length > 16) {
alert('长度必须介于6-16位之间');
return
}
let area = ['@','*','-','a', 'b', 'c', ...rest]
for (let i = 0; i < value.length; i++) {
//判断是否存在传入的value和area字符是否有不一样
}
}
//验证简单密码
let reg = /^\w{6,16}$/
let reg = /^[\u4e00-\u9FA5]{2,10}(.[\u4e00-\u9FA5]+)?$/
规则分析
1.开头是数字字母下划线(1到多位)
2.还可以是 -、数字、字母、下划线、.数字字母下划线,整体零到多次
3.邮箱的名字由"数字、字母、下划线、-、.几部分组成,但是-/,不能连续多次出现"
let reg=/^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/
规则分析
1.前6位为地区编号
2.7到10位为出生年份
3.11到12位为出生月份
4.13到14位为出生日期
5.倒数第二位判断男女
6.最后一位为\d|x
let reg=/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(?:\d|x)$/
let time='2019-09-03'
let reg=/^(\d{4})-(\d{1,2})-(\d{1,2})$/
time=time.replace(reg,"$1年$2月$3日")//=>2019年9月3日
/*
还可以这样处理[str].replace([reg],[function])
1.首先拿REG和TIME进行匹配捕获,能匹配到几次就会把传递的函数执行几次(而且是匹配一次执行一次)
2.不仅把方法执行,而且REPLACE还给方法传递了实参信息(和exec捕获的内容一致的信息:大正则匹配的内容,小分组匹配的信息...)
3.在函数中我们返回的是啥,就把当前大正则匹配的内容替换
*/
time = time.replace(reg, (...arg) => {
let [, $1, $2, $3] = arg
$2.length < 2 ? $2 = "0" + $2 : null
$3.length < 2 ? $3 = "0" + $3 : null
return $1 + "年" + $2 + "月" + $3 + "日"
})
let str="good good study. day day up!"
let reg = /\b([a-zA-Z])[a-zA-Z]*\b/g
//=>函数被执行了六次,每一次都把正则匹配信息传递给函数
//=>每一次ARG:["good","g"]["good","g"]["study","s"]...
str = str.replace(reg, (...arg) => {
let [content, $1] = arg
$1 = $1.toUpperCase()
content = content.substring(1)
return $1 + content
})
let str='helloWorldHello'
/*
简单思维
*/
let obj=[]
[].forEach.call(str,char=>{
if(typeof obj[char]!=="undefined"){
obj[char]++
return;
}
obj[char]=1
})
//使用正则
let str="efaadfaeeadq"
str=str.split('').sort((a,b)=>a.localeCompare(b)).join(''));
let reg=/([a-zA-Z])\1+/g
let ary=str.match(reg)
ary.sort((a,b)=>{
return b.length-a.length
})
let max=ary[0].length,
res=[ary[0].substring(0,1)]
for (let i = 1; i < ary2.length; i++) {
let item = ary2[i]
if (item.length < max) {
break
}
res2.push(item.substring(0, 1))
}
console.log(`出现次数最多的字符:${res}出现了${max}次`)
//使用正则2
let str = "eeefadsfadfdfddfd",
max = 0,
res = [],
flag = false
str = str.split('').sort((a, b) => a.localeCompare(b)).join('')
console.log(str)
for (let i = str.length; i > 0; i--) {
let reg = new RegExp(`([a-zA-Z])\\1{${(i-1)}}`, 'g')
str.replace(reg, (content, $1) => {
res.push($1)
max = i;
flag = true
})
if (flag) break
}
console.log(`出现次数最多的字符:${res}出现了${max}次`)
~ function () {
function formatTime(template = "{0}年{1}月{2}日 {3}时{4}分{5}秒") {
let timeAry = this.match(/\d+/g)
console.log(timeAry)
return template.replace(/\{(\d+)\}/g, (...[, $1]) => {
let time = timeAry[$1] || "00"
return time.length < 2 ? "0" + time : time
})
}
function queryURLParams() {
let obj = {}
this.replace(/([^?=]+)=([^?=]+)/g, (...[, $1, $2]) => {
obj[$1] = $2
})
this.replace(/#([^?=]+)/g, (...[, $1]) => {
obj['HASH'] = $1
})
return obj
}
['formatTime', 'queryURLParams'].forEach(item => {
String.prototype[item] = eval(item)
})
}()
let time = "2019-9-4 16:51:3"
console.log(time.formatTime())
console.log(time.formatTime("{0}年{1}月{2}日"))
console.log(time.formatTime("{1}-{2} {3}-{4}"))
//queryURLParams:获取URL地址问号和面的参数信息(可能也包含hash值)
let url = "http://www.baidu.com?x=12jkadfl&form=asldfk#video"
console.log(url.queryURLParams())
//普通方式来做
let num="112345678256874"
num=num.split('').reverser().join('')
for(let i=2;i<num.length-1;i+=4){
let prev=num.substring(0,i+1),
next=num.substring(i+1)
num=prev+","+next
}
num=num.split('').reverse().join('');
console.log(num)
//正则方式
String.prototype.millimeter = millimeter
let num2 = "112345678256874"
function millimeter() {
return this.replace(/\d{1,3}(?=(\d{3})+$)/g, content => {
return content + ','
})
}
console.log(num2.millimeter())
/.+\\(.+)$/
正则的捕获
1.正则Rep.prototype上的方法
exec
test
2.字符串String.prototype上支持正则表达式处理的方法
replace
match
spite
let str="helloWorld1998@0522@link"
//=>正则捕获的贪婪性:默认情况下,正则捕获的时候是按当前所匹配的最长结果来获取的
let reg=/\d+?/g //=>(9) ["2", "0", "1", "9", "1", "9", "2", "1", "1"]
//这里在量词后面设置?表示捕获的时候取消贪婪性(按照正则匹配的最短结果来获取)
str.match(reg)
let str="hello19129world2910"
let reg=/\d+/
let reg2=/\d+/g
reg.exec(str)
/*
Array(1)
0: "19129"
groups: undefined
index: 8 这里是数字开始的索引
input: "hello19129world2910"
length: 1
__proto__: Array(0)
*/
reg.lastIndex //0
//=>这里因为没有加g修饰符,所以每执行一次exec只能捕获到一个符合规则,默认情况下lastIndex最后为0,这就是正则捕获的懒惰性
reg2.exec(str)
/*
0: "19129" 第一个匹配到的索引字符串的开始位置
groups: undefined
index: 8 这里是索引字符串开始的索引
input: "hello19129world2910"
length: 1
__proto__: Array(0)
*/
reg2.lastIndex //13 这是索引字符串的最后一个字符索引
reg2.exec(str)
/*
0: "2910"
groups: undefined
index: 19
input: "hello19129world2910"
length: 1
__proto__: Array(0)
*/
reg2.lastIndex //23
let reg = /\d+/g;
~ function () { //匿名函数的直接调用
function execAll(str = "") {
if (!this.global) return this.exec(str) //判断是否存在全局g修饰符
let ary = []
res = this.exec(str);
while (res) {
ary.push(res[0]);
res = this.exec(str)
}
return ary
}
RegExp.prototype.execAll = execAll
}()
reg.execAll("hello19129world2910")
/*
0: "19129"
1: "2910"
length: 2
__proto__: Array(0)
*/
"hello19129world2910".match(reg)
/*
0: "19129"
1: "2910"
length: 2
__proto__: Array(0)
*/
let str = '50022720001121000X'
let reg = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(?:\d|X)$/ //这里(?:)取消了捕获
reg.exec(str)
str.match(reg)
/*
0: "50022720001121000X"
1: "500227"
2: "2000"
3: "11"
4: "21"
5: "00"
6: "0"
groups: undefined
index: 0
input: "50022720001121000X"
length: 7
__proto__: Array(0)
*/
let str='helloWorld@78128@helloWorld'
str.replace(/helloWorld/g,'hahaha') //=>hahaha@78128@hahaha
let str="book"
let reg=/^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/
//=>分组引用就是通过"\数字"让其代表和对应分组出现一模一样的内容
reg.test('book')//true
reg.test('deep')//true
reg.test('depp')//false