0%

正则表达式

m多行匹配修正符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let hd= `
#1 js, 200元 #
#2 php,300元 #
#9 houdunfren.com # 后盾人
#3 node.js, 180元 #
`;

let reg = hd.match(/^\s*#\d+\s+.+\s+#$/gm)
let result = reg.map(v=>{
v=v.replace(/^\s*#\d+\s*/,'').replace(/#/,'');
// console.log(v);
[name,price] =v.split(',');
return {name,price};
})
console.dir(result);

汉字和字符属性

exec具有lastIndex属性,每次执行只会匹配一次,于此同时回更新index的值,并包含属性,而使用match函数的话在全局匹配下时没有显示属性的

1
2
3
4
let hd= "houdunren";
let reg = /\w/g;
console.log(reg.exec(hd));
console.log(reg.exec(hd));

执行结果

1
2
["h", index: 0, input: "houdunren", groups: undefined]
["o", index: 1, input: "houdunren", groups: undefined]

如果一个正则对象不是全局(global)的,则其lastIndex属性会被完全忽略(不会读取,也不会赋值).

区别一:全局匹配(/g)操作会读取还会更新lastIndex属性的值.类似于全局匹配,粘滞匹配(/y)也会让这样做.不过会有点区别,就是如果是全局匹配,在匹配失败后,lastIndex属性的值会被重置为0,但粘滞匹配不会.

区别二: 粘滞匹配不能像普通正则那样,跳过那些匹配失败的字符后接着执行后面字符的匹配操作.在本例中就是,/o/在匹配字符f失败之后,就完全失败了,不会接着匹配f后面的o

1
2
/o/.test("foo")     //true
/o/y.test("foo") //false

粘滞的意思就是”使用隐式的^锚点把正则锚定在了lastIndex所指定的偏移位置处。

y模式(粘滞匹配)

1
2
3
4
5
6
7
8
9
let hd = `后盾人QQ群:11111111,99999999,88888888
后盾人不断分享视频教程,后盾人网址是houdunren.com`;
let reg = /(\d+),?/y;
reg.lastIndex=7;
// console.log(reg.exec(hd));
let qq= [];
while((res = reg.exec(hd))){
qq.push(res[1])}//res返回一个数组,res[1]数组的第二个属性为匹配到的值
console.log(qq);

原子表,按单一字符匹配

1
2
3
let tel = '2022/02/23'
let reg= /^\d{4}([-\/])\d{2}\1\d{2}$/g; // \1表示要和前面的原子组(([-\/])保持一致
console.log(tel.match(reg));

!!!!!注意原子表中的字符不解析。例如()表示原子组,但是在原子表里面它就是普通括号

1
2
3
4
let hd = "(houdnren.com).+";
console.log(hd.match(/[()]/gi));
输出结果:
["(", ")"]

区间匹配

1
2
3
4
5
6
7
8
9
<body>
<input type="text" name='username'>
<script >
let input = document.querySelector('input');
input.addEventListener('keyup',function(){
this.value.match(/^[a-z]\w{3,6}$/i)//这里其实是4-7位,[a-z]算一位
})
</script>
</body>

排除匹配

1
2
let hd = `张三:010-99999999,李四:020-8888888`;//注意这里的冒号是的中英文格式要一致
console.log(hd.match(/[^\d:\-,\s]+/g)); //[^\d:\-,\s]匹配排除

!!!!匹配排除的和区间匹配的重要区别是^是一个在方括号的里面,一个在方括号的外面

匹配中文的方式

1
hd.match(/\p{sc=Han}+/gu)

嵌套分组与不记录组

1
2
3
4
5
6
7
8
9
10
let hd=`
https://www.houdunren.com
http://houdunwang.com`;

let result=[];
let reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|org|cn))/ig;
while(res=reg.exec(hd)){
result.push(res[1])
}
console.log(result);

在原子组()的前面加?:表示这个组不会被记录下来(1:第一个组;2:第二个组)

输出结果

1
2
3
4
5
["www.houdunren.com", "houdunwang.com"]
0: "www.houdunren.com"
1: "houdunwang.com"
length: 2
__proto__: Array(0)

批量使用正则完成密码匹配

将密码用数组包起来,然后用数组的every方法遍历全部满足的请款

1
2
3
4
5
6
7
8
9
10
11
12
let input=document.querySelector('input');
input.addEventListener('keyup',()=>{
let value = event.target.value;

const regs =[
/^[a-z0-9]{5,10}$/i,
/[A-Z]/,
]

let status=regs.every(e=>e.test(value));
console.log(status?'正确':'错误');
})

禁止贪婪?

1
2
3
4
let hd ="hdddd";
console.log(hd.match(/hd{2,3}?/));//此时只能匹配到hdd(2个d)
console.log(hd.match(/hd*?/));//此时只能匹配到h(*表示0个或者多个)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HTML部分

<main>
<span>houdunrenwang</span>
<span>hdcms</span>
<span>houdunren.com</span>
</main>

JS部分
const main=document.querySelector('main')

let reg= /<span>([\s\S]+?)<\/span>/gi;
// console.log(main.match(reg));
main.innerHTML = main.innerHTML.replace(reg,(v,p1)=>{
console.log(p1); //v是匹配到的字符串,p1是原子组的内容。
return `<h4 style="color: red">后盾人-${p1}</h4>`

})

使用matchAll完成全局匹配

1
2
3
4
5
6
7
8
9
10
11
let reg = /<(h[1-6])>([\s\S]+?)<\/\1>/ig;
const body = document.querySelector('main');
let contents=[];
let hd= document.body.innerHTML.matchAll(reg);
for (const iterator of hd) {
console.dir(iterator);
contents.push(iterator[2])
}
console.table(contents);


为低端浏览器定义原型方法matchAll

1
2
3
4
5
6
7
8
9
10
String.prototype.matchAll=function(reg){
let res = this.match(reg);
if(res){
let str = this.replace(res[0],"^".repeat(res[0].length));
let match = str.matchAll(reg) || [ ];
return [res, ...match];
}
}
let hd = 'houdunren.com';
console.log(hd.matchAll(/(u)/

使用exec完成全局匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
html部分
<h1>houdunren.com</h1>
<h2>hscms.com</h2>
<h1>后盾人</h1>

JS 部分
<script >
function searchs( string, reg){
let result=[];
while(res=reg.exec(string)){
result.push(res)
}
return result;
}
let matchs = searchs(document.body.innerHTML, /<(h[1-6])>([\s\S]+?)<\/\1>/ig);
console.log(matchs);
</script>

$&的使用

1
2
3
4
5
6
7
8
9
html部分
<main>
在线教育是一种高效的学习方式,教育是一生的事业
</main>
JS部分
let main = document.querySelector('body main');
main.innerHTML=main.innerHTML.replace(/教育/g,"<a href=https://www.hdcms.com>$&</a>")
//$&可以取到匹配到的值

原子组别名

1
2
3
4
5
6
7
let hd= `
<h1>houdunren</h1>
<span>后盾人</span>
<h2>hdcms</h2>
`
let reg = /<(h[1-6])>(?<con>.*?)<\/\1>/ig; //?<con>取别名的地方
console.log(hd.replace(reg,"<h4>$<con></h4>")); //$<con>使用别名

零宽先行断言

1
2
3
4
5
6
7
8
9
10
11
12
13
html部分

<main>
后盾人不断分享视频教程,学习后盾人教程提升编程能力。
</main>

JS部分

let main = document.querySelector('main');
let reg = /后盾人(?=教程)/g; //表示后盾人后面是教程的
main.innerHTML= main.innerHTML.replace(reg,`
<a href="https://houdunren.com">$&</a>`)

零宽后行断言

1
2
3
4
5
6
7
8
9
10
11
12
html代码
<mian>
<a href ="https://baidu.com">百度</a>
<a href="https://yahu.com">雅虎</a>
</mian>

JS
const mian= document.querySelector('mian');
let reg = /(?<=href=(['"])).+(?=\1)/ig; //断言不是组
console.log(mian.innerHTML.match(reg));
mian.innerHTML=mian.innerHTML.replace
(reg,"https://houdunren.com")

电话号码后四位模糊处理

1
2
3
4
5
6
7
8
9
10
let users=`
向军电话:12345678999
后盾人电话:89893893893
`;
let reg =/(?<=\d{7})\d{4}/gi;
// console.log(users.match(reg));
users = users.replace(reg,v=>{ //v是匹配到的内容8999,3893
return '*'.repeat(4)
})
console.log(users);

零宽负向先行断言

1
2
3
let hd = "houdunren2010hdcms";
let reg = /[a-z]+(?!\d+)$/ig; 不加$的话,houdunre也会匹配到
console.log(hd.match(reg));

断言限制用户名关键词

1
2
3
4
5
6
let input = document.querySelector(`input`);
input.addEventListener('keyup',function(){
const reg = /^(?!.*向军.*).*/i; //用户名不能存在向军开头,注意如果在向军的前后不加.*的话匹配会存在问题向军在别的字符后面的情况会被匹配到。
console.log(this.value.match(reg));
});

零宽负向后行断言(前面不能是……)

1
2
3
4
let hd = "hdcms99houdunren";
let reg = /^(?<!\d+)[a-z]+/ig;
console.log(hd.match(reg));

使用断言排除法同一数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
html部分
<main>
<a href="https://www.houdunren.com/1.jpg">1.jpg</a>
<a href="https://oss.houdunren.com/2.jpg">2.jpg</a>
<a href="https://cdn.houdunren.com/2.jpg">3.jpg</a>
<a href="https://houdunren.com/2.jpg">后盾人</a>
</main>

js部分
let main =document.querySelector('main');
const reg = /https:\/\/([a-z]+)?(?<!oss)\..+?(?=\/)/ig;
console.log(main.innerHTML.match(reg));
main.innerHTML=main.innerHTML.replace(reg, v=>{
return "https://oss.houdunren.com"
});