正则表达式 - 语法
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
例如:
-
runoo+b,可以匹配 runoob、runooob、runoooooob 等,+ 号代表前面的字符必须至少出现一次(1次或多次)。
-
runoo*b,可以匹配 runob、runoob、runoooooob 等,* 号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。
-
colou?r 可以匹配 color 或者 colour,? 问号代表前面的字符最多只可以出现一次(0次、或1次)
一下下得demo例子:
找出字符串中得数字:
let str="yangdongxu1991-11-02 and you";
str.match(/\d/g).join("");//19911102
正则表达式字面量的书写:
let str='yangdongxu';
/u/.test(str);//true
let a='u';
console.log(eval(`/${a}/`).test(str))//true eval可以使用变量的形式
使用对象创建正则:实现检索到的内容飘红
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div>
my name is yangdongxu?how are you?
</div>
</body>
</html>
<script type="text/javascript">
let con=prompt('请输入要检测的内容','支持正则');
let reg=new RegExp(con,"g");
document.querySelector('div').innerHTML=document.querySelector('div').innerHTML.replace(reg,search=>{
return `<span style="color:red">${search}</span>`
})
</script>
正则表达式选择符的使用:
let tel='010-9999999';//北京或者上海的电话号
console.log(/(010|020)\-\d{7,8}/.test(tel))//true
原子表和原子组中的选择符:
eg:[]表示原子表 里面的东西表示或选择一个值匹配
let reg=/[123456]/;
let b='1';
b.match(reg);//1
eg:原子组匹配所有
let reg=/(12|34)/ //匹配的是12或34
let hd='1234567';
hd.match(reg);//12
字符边界约束:
只要a中有数字就匹配:
let a='3';
let b=/\d/;
b.test(a)//只要a中有数字就匹配 true
限定符要登场了:限定以数字开始以数字结束
let a='233a';
let reg=/^\d$/;
reg.test(a);//有字母返回的就是false
限定符判断用户名是指定位数:eg:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input type="text" name="username">
<span></span>
</body>
</html>
<script type="text/javascript">
//监听键盘点击事件判断用户名 方法1:
/*document.querySelector("[name='username']").onkeyup=function(e){
let flag=this.value.match(/^[a-z]{3,6}$/);//查找3-6位的字母用户名
let test=flag?'正确':'错误';
document.querySelector('span').innerHTML=test;
}*/
//方法2:
document.querySelector("[name='username']").addEventListener('keyup',function(){
let flag=this.value.match(/^[a-z]{3,6}$/);
document.querySelector('span').innerHTML=flag?"正确":'错误';
})
</script>
匹配一个字符串中的所有电话号:\d匹配所有数字 \D匹配所有不是数字的
let str='杨冬旭:010-12345678;李四:102-88888888';
str.match(/\d{3}-\d{7,8}/g)//[010-12345678,102-88888888];
let a='zhang1991';
a.match(/\D/);//['z'] 匹配上就成功了了 停止继续查找了
a.match(\D);//['zhang'] 匹配所有不是数字的
找出字符串中的所有汉字:\s表示空格符 \S除了空白
let str=' 杨冬旭:010-12345678;李四:102-88888888';
str.match(/[^\s:\d-;:]+/g)//["杨冬旭:", "李四:"]
\w表示字母数字下划线 \W表示字母数字下划线之外的任意字符:
//实现匹配邮箱
let email='a1152718127@qq.com';
email.match(/^\w+@\w+.\w+$/);//["a1152718127@qq.com"];
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
<script type="text/javascript">
let con=prompt('请输入用户名字?','yang123_w');
console.log(/^[a-z]\w{4,9}$/.test(con))//输入字母开头内容是字母数字下划线组成的5到10位数字
</script>
m多行匹配修正符:m每行单独处理
let hd=`
#1 js,200元 #
#2 js,600元 #
#3 php,400元 # 后盾人
#8 java,800元 #
`
hd.match(/^\s*#\d+.+#$/gm).map((v)=>{
v=v.replace(/\s+#\d+\s*/,"").replace(/\s+#/g,"")
let [name,price]=v.split(',');
return JSON.stringify({name,price});
})// ["{"name":"js","price":"200元"}", "{"name":"js","price":"600元"}", "{"name":"java","price":"800元"}"]
lastIndex记住上一次每一个点的信息:lastIndex 属性用于规定下次匹配的起始位置。
注意: 该属性只有设置标志 g 才能使用。
上次匹配的结果是由方法 RegExp.exec() 和 RegExp.test() 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。
注意:该属性是可读可写的。只要目标字符串的下一次搜索开始,就可以对它进行设置。当方法 exec() 或 test() 再也找不到可以匹配的文本时,它们会自动把 lastIndex 属性重置为 0。
exec(): 方法用于检索字符串中的正则表达式的匹配。返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
let hd="houdunren";
hd.match(/\w/g)//["h", "o", "u", "d", "u", "n", "r", "e", "n"];
let reg=/\w/g;
reg.exec(hd);//["h"]
reg.exec(hd);//["o"]
//想要打印全部需要循环
while(res=reg.exec(hd)){
console.log(res)
}/*["u", index: 2, input: "houdunren", groups: undefined]
VM230:8 ["d", index: 3, input: "houdunren", groups: undefined]
VM230:8 ["u", index: 4, input: "houdunren", groups: undefined]
VM230:8 ["n", index: 5, input: "houdunren", groups: undefined]
VM230:8 ["r", index: 6, input: "houdunren", groups: undefined]
VM230:8 ["e", index: 7, input: "houdunren", groups: undefined]
VM230:8 ["n", index: 8, input: "houdunren", groups: undefined]*/
汉字和标点符号:{sc=Han}
let hd='yangdongxu2020,你是最棒的,加油 成为最好的自己!';
hd.match(/\p{L}/gu);
//检测字符属性\p {L}表示检测字母 u表示匹配宽字符:不管多长的都匹配
//["y", "a", "n", "g", "d", "o", "n", "g", "x", "u", "你", "是", "最", "棒", "的", "加", "油", "成", "为", "最", "好", "的", "自", "己"] 但是我匹配到了字符和汉字这是我比较疑惑的 为什么有汉字
hd.match(/\p{P}/gu)//得到字符中的标点 [",", ",", "!"]
//匹配汉字
hd.match(/\p{sc=Han}/gu);//sc=Han 找到所有汉字 ["你", "是", "最", "棒", "的", "加", "油", "成", "为", "最", "好", "的", "自", "己"]
let str="🙂";
str.match(/[🙂]/)//["�", index: 0, input: "🙂", groups: undefined]
str.match(/[🙂]/u)//["🙂", index: 0, input: "🙂", groups: undefined] u表示已宽字符匹配
lastIndex属性:exec匹配满足条件的字符串 执行一次匹配 lastIndex数字加1 正则中要加g全局模式不然lastIndex始终是0
let str='yangdongxu';
let reg=/\w/g;
console.log(reg.lastIndex);//0
console.log(reg.exec(str));['y'];
console.log(reg.lastIndex);//1
console.log(reg.exec(str));['a'];
console.log(reg.lastIndex);//2
console.log(reg.exec(str));['n'];
y模式:找到就不往下去找了
let hd="开始总是难得,12345,1,2,2,掌声,李四1314,1";
let reg=/\d+,?/y;
reg.lastIndex=7;
let arr=[];//从第七得位置开始找 y:找到就继续 找不到就停止
while(res=reg.exec(hd)){
arr.push(res[0])
}
console.log(arr);
原子表基本模式:
let tel="2012/11/11";
let reg=/^\d{4}([-\/])\d{2}\1\d{2}$/;
tel.match(reg);//([-\/])里面是啥 \1就是啥 ["2012/11/11", "/", index: 0, input: "2012/11/11", groups: undefined]
排除匹配:
let str="张三:11-11,李四:111,lizi";
str.match(/[^\d:\-,]+/g)//["张三:", "李四", "lizi"]
//解释:[^]里面得东西表示除了这里面之外得内容
认识原子组:
//认识原子组
let hd=`
<h1>yangdongxu</h1>
<h2>yangdongxu</h2>
`;
let reg=/<(h[1-6])>([\s\S]*)<\/\1>/gi
console.log(hd.match(reg))// ["<h1>yangdongxu</h1>", "<h2>yangdongxu</h2>"]
邮箱验证中原子组的使用:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input type="text" name="email">
<span></span>
</body>
</html>
<script type="text/javascript">
let reg=/^[\w-]+@([\w-]+\.)+(com|cn|org|cc|net)$/i;
document.querySelector('[name="email"]').addEventListener('keyup',function(){
// debugger
document.querySelector('span').innerHTML=reg.test(this.value)?'正确':'错误'
})
</script>
原子组引用完全替换操作:
let str=`
<h2>yangsdkgks</h2>
<h1>taige</h1>
`;
let reg=/<(h[1-6])>([\s\S]+)<\/\1>/gi
let newReg=str.replace(reg,(p,p1,p2)=>`<span>{p2}</span>`);
console.log(newReg);//p2表示第二个原子组[\s\S] <span>{p2}</span>
// <span>{p2}</span>
嵌套分组与不记录组:找到所有域名
let str=`
http://www.abc.com
http://hd98.com
https://baidudjdsas.com
`;
let reg=/https?:\/\/(?:\w+\.)?(\w+\.(?:com|org|cn))/gi
// console.log(reg.exec(str))
let arr=[];
while((res=reg.exec(str))){
console.log(reg.lastIndex);
arr.push(res[1])
}
console.log(arr); ["abc.com", "hd98.com", "baidudjdsas.com"]
批量使用正则完成密码验证:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input type="text" name="password">
<span></span>
</body>
</html>
<script type="text/javascript">
//批量使用正则完成密码验证
let ele=document.querySelector("[name='password']").addEventListener('keyup',(e)=>{
let val=e.target.value;
let reg=[/^[a-z0-9]{5,9}$/i,/[A-Z]/,/[0-9]/];
let bool=reg.every(item=>item.test(val))//密码中要满足包含三种匹配才算是成功
console.log(bool?"正确":'错误');
})
</script>
标签替换禁止贪婪的使用:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<main>
<span>yangdongx</span>
<span>lxyD</span>
<span>xiaoh</span>
</main>
</body>
</html>
<script type="text/javascript">
//标签替换禁止贪婪的使用
//span标签改成h4 文字前边加上"后盾人-"
let main=document.querySelector('main');
const reg=/<span>([\s\S]+?)<\/span>/gi;
main.innerHTML=main.innerHTML.replace(reg,(v,p1)=>{
// console.log(v);
return `<h4 style="color:red">后盾人-${p1}</h4>`
})
</script>