正则表达式都是操作字符串的
作用:对数据进行查找、替换、有效性验证
创建正则表达式的两种方式:
// 字面量方式 /js/ // 构造函数方式 regular expression new RegExp()
普通字符:字母 数字 汉字 _ 空格 ; , @ (没有特殊含义的符号)
两种匹配的方式:
test 测试,找到返回true,反之为false
exec 匹配字符,找到的话就返回该字符(以数组形式),反之返回null
这两个都是属于正则的方法,所以前面是跟的正则
var str="i love js"; var pattern=/js/; console.log(pattern.test(str));//true console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined] var pattern=/Js/; console.log(pattern.test(str));//false console.log(pattern.exec(str));//null
正则默认情况下是区分大小写的
使用模式修饰符可以设置不区分大小写
三种模式修饰符:
i ignoreCase 忽略大小写
g global 全局匹配
m multiline 多行匹配
var str="i love js"; var pattern=/Js/i; console.log(pattern.test(str));//true console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]
i g m这三个模式修饰符可以任意组合,无顺序要求
var str="i love js"; var pattern=new RegExp("js"); console.log(pattern.test(str));//true console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined] var pattern=new RegExp("Js"); console.log(pattern.test(str));//false console.log(pattern.exec(str));//null var pattern=new RegExp("Js","i"); console.log(pattern.test(str));//true console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]
字面量方式与构造函数方式的区别:
/js/i 直观简洁
new RegExp("js", "i") 可以由于变量的检测
var str="i love js"; var userInput="js";//需要匹配的字符在变量中 var pattern=/userInput/i;//该方式不可取,直接匹配的是userInput console.log(pattern.test(str));//false console.log(pattern.exec(str));//null var userInput="js";//需要匹配的字符在变量中 var pattern="/"+userInput+"/i";//该方式不可取,正则变为了字符串,不再具有test和exec方法 console.log(typeof pattern);//string console.log(pattern.test(str));//报错 console.log(pattern.exec(str));//报错 var pattern=new RegExp(userInput,"i"); console.log(typeof pattern);//object 正则属于正则对象 console.log(pattern.test(str));//true console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]
简单的转义字符
/ 表示正则的边界,匹配时需要进行转义
var str="//我是注释"; var pattern=////; console.log(pattern.exec(str));// ["//", index: 0, input: "//我是注释", groups: undefined]
字符串中如果存在 ,默认会对下一个字符进行转义,如果需要作为普通字符处理,就对转义字符 再进行转义处理 \
var str="\\"; console.log(str);// 结果只显示\
普通字符加上 可能会有特殊含义
如 代表换行
var str="nba"; var pattern=/n/; console.log(pattern.exec(str));//匹配n ["n", index: 0, input: "nba", groups: undefined] var pattern2=/ /; console.log(pattern2.exec(str));//匹配换行符 null
匹配 tab键
var str=" hello"; var pattern=/ /; console.log(pattern.exec(str));//匹配n [" ", index: 0, input: " hello", groups: undefined]
可以用 ascii码 来正则匹配字符
var str="hello cyy"; var pattern=/x0A/; console.log(pattern.exec(str));//匹配 ["↵", index: 5, input: "hello↵cyy", groups: undefined]
可以用 unicode 编码来正则匹配字符
var str=" 前面是tab键"; var pattern=/u0009/; console.log(pattern.exec(str));//匹配tab键 [" ", index: 0, input: " 前面是tab键", groups: undefined]
unicode 常用于匹配汉字
匹配一个字符串中的所有中文:u4e00-u9fa5
var str="i am 陈莺莺"; var pattern=/[u4e00-u9fa5]/; console.log(pattern.exec(str));//匹配中文 ["陈", index: 5, input: "i am 陈莺莺", groups: undefined]
可以匹配换行符的有: x0A u000A
字符类
[ ] 匹配中间的任意一个字符
var str="javascript"; var pattern=/[js]/; console.log(pattern.exec(str));//匹配j ["j", index: 0, input: "javascript", groups: undefined]
[^ ] 表示取反
var str="javascript"; var pattern=/[^js]/;//匹配除了j和s之外的 console.log(pattern.exec(str));// ["a", index: 1, input: "javascript", groups: undefined]
[ ] 中间可以是一个范围
var str="javascript"; var pattern=/[k-z]/;//匹配k-z之间的字母 console.log(pattern.exec(str));// ["v", index: 2, input: "javascript", groups: undefined]
表示范围时,前面的必须小于等于后面的
var str="javascript"; var pattern=/[c-c]/;//前面等于后面 console.log(pattern.exec(str));// ["c", index: 5, input: "javascript", groups: undefined] var pattern2=/[c-b]/;//前面大于后面 console.log(pattern2.exec(str));// 报错
同时匹配大小写字母
var str="JavaScript"; var pattern=/[a-zA-Z]/;//前面等于后面 console.log(pattern.exec(str));// ["J", index: 0, input: "JavaScript", groups: undefined]
匹配所有数字 0-9
var str="JavaScript3333"; var pattern=/[0-9]/; console.log(pattern.exec(str));// ["3", index: 10, input: "JavaScript3333", groups: undefined]
[ ] 中间可任意组合,如
[a-zA-Z0-9@_]
常用的字符类:
. 匹配所有除了 之外的字符
var str="3.14"; var pattern=/./; console.log(pattern.exec(str));// ["3", index: 0, input: "3.14", groups: undefined]
如果单纯匹配 . 转义即可
var str="3.14"; var pattern=/./; console.log(pattern.exec(str));// [".", index: 1, input: "3.14", groups: undefined]
. 不能匹配换行符
var str=" "; var pattern=/./; console.log(pattern.exec(str));// null
数字字母下划线
/[a-zA-Z0-9_]/ = /w/
/[^a-zA-Z0-9_]/ = /W/
var str="@_"; var pattern=/w/; console.log(pattern.exec(str));// ["_", index: 1, input: "@_", groups: undefined]
数字
/[0-9]/ = /d/
/[^0-9]/ = /D/
var str="@_123"; var pattern=/d/; console.log(pattern.exec(str));// ["1", index: 2, input: "@_123", groups: undefined]
/ / 匹配空格
/ / 匹配 tab
/s/ 匹配空格或者制表符(tab)
/S/ 匹配除了空格或者制表符之外的其他字符
匹配的顺序取决于字符串中的顺序
var str=" 9"; var pattern=/[ds]/; console.log(pattern.exec(str));// [" ", index: 0, input: " 9", groups: undefined]
重复
{n} 表示量词,出现 n 次
var str="123456789"; var pattern=/d{3}/;//匹配3个数字 console.log(pattern.exec(str));// ["123", index: 0, input: "123456789", groups: undefined]
{n1, n2} 表示出现次数大于等于n1,小于等于n2
var str="123456789"; var pattern=/d{2,3}/;//匹配2-3个数字,会尽可能多的匹配 console.log(pattern.exec(str));// ["123", index: 0, input: "123456789", groups: undefined]
{n1, } 表示大于等于n1
{ ,n2 } 不表示小于等于n2,这种写法是错误的
var str="123456789"; var pattern=/d{1,}/; console.log(pattern.exec(str));// ["123456789", index: 0, input: "123456789", groups: undefined] var pattern2=/d{,2}/;//这种写法是错误的 console.log(pattern2.exec(str));// null
? = {0,1} 匹配0次或者1次
var str="123456789"; var pattern=/d?/; console.log(pattern.exec(str));// ["1", index: 0, input: "123456789", groups: undefined]
+ = {1,} 至少1次
var str="123456789"; var pattern=/d+/; console.log(pattern.exec(str));// ["123456789", index: 0, input: "123456789", groups: undefined]
* = 任意次(包括0次)
var str="123456789"; var pattern=/d*/; console.log(pattern.exec(str));// ["123456789", index: 0, input: "123456789", groups: undefined]
匹配价格
var str="肯德基豪华午餐¥15.5元"; var pattern=/d+.?d*/; //前面的数字 至少有1位 //. 出现0次或者1次 //后面的数字 可以有也可以没有,任意次 console.log(pattern.exec(str));// ["15.5", index: 8, input: "肯德基豪华午餐¥15.5元", groups: undefined]
匹配正整数和负整数
var str="肯德基豪华午餐¥15.5元"; var pattern=/-?[1-9]d*/; var pattern=/-{0,1}[1-9]d*/;
非贪婪的重复
正则匹配默认是贪婪模式,存在量词时会尽可能多的匹配
var str="aaab"; var pattern=/a+/; console.log(pattern.exec(str));//["aaa", index: 0, input: "aaab", groups: undefined]
在量词后面加上 ? ,表示由贪婪模式转为非贪婪模式,尽可能少的匹配
var str="aaab"; var pattern=/a+?/; console.log(pattern.exec(str));//["a", index: 0, input: "aaab", groups: undefined]
但是正则有一个原则,就是去找第一个可能匹配的字符
而不是最合适的位置
var str="aaab"; var pattern=/a+?b/;//此处并不会匹配到ab console.log(pattern.exec(str));//["aaab", index: 0, input: "aaab", groups: undefined]
如上,并不会匹配到ab,因为正则从0开始就匹配到了a,之后会一直沿着下去寻找b
贪婪匹配与非贪婪匹配的应用
var str="<td>第一格</td><td>第二格</td>"; var pattern=/<td>.*</td>/;//贪婪模式,匹配两格 console.log(pattern.exec(str));//["<td>第一格</td><td>第二格</td>", index: 0, input: "<td>第一格</td><td>第二格</td>", groups: undefined] var pattern2=/<td>.*?</td>/;//非贪婪模式,匹配一格 console.log(pattern2.exec(str));//["<td>第一格</td>", index: 0, input: "<td>第一格</td><td>第二格</td>", groups: undefined]
选择 |
var str="css js"; var pattern=/js|html|css/; console.log(pattern.exec(str));//["css", index: 0, input: "css js", groups: undefined]
选择最先匹配的,而不是最合适的
var str="ab"; var pattern=/a|ab/;//先尝试匹配a,匹配成功后,不再匹配ab console.log(pattern.exec(str));//["a", index: 0, input: "ab", groups: undefined]
正则匹配上传图片的后缀名:一般图片的后缀名有gif,jpg,jpeg,png等,并且不区分大小写
/.gif|.jpg|.jpeg|.png/i
分组和引用 ()
var str="abab"; var pattern=/(ab)+/;//将ab看成一个整体 console.log(pattern.exec(str));//(2) ["abab", "ab", index: 0, input: "abab", groups: undefined]
返回的数组中,第一个元素是匹配到的结果,第二个元素是 () 中分组的元素
( ) 捕获分组
(?: ) 不捕获分组
var str="abcd"; var pattern=/(abc)d/;//匹配到abcd,捕获到abc console.log(pattern.exec(str));//(2) ["abcd", "abc", index: 0, input: "abcd", groups: undefined] var str="abcd"; var pattern=/(?:abc)d/;//匹配到abcd,没有捕获 console.log(pattern.exec(str));//(2) ["abcd", index: 0, input: "abcd", groups: undefined]
平行分组依次返回
var str="abcd"; var pattern=/(ab)(cd)/;//匹配到abcd,第一个分组ab,第二个分组cd console.log(pattern.exec(str));//["abcd", "ab", "cd", index: 0, input: "abcd", groups: undefined]
嵌套分组,按左边括号的顺序来进行返回
var str="abcd"; var pattern=/(a(b(c(d))))/; console.log(pattern.exec(str));//(5) ["abcd", "abcd", "bcd", "cd", "d", index: 0, input: "abcd", groups: undefined]
可以在正则中直接使用分组 代表第n个分组
var str="abcdab"; var pattern=/(ab)cd1/;//1代表第一个分组,即ab console.log(pattern.exec(str));//(2) ["abcdab", "ab", index: 0, input: "abcdab", groups: undefined]
分组的实际应用
匹配外层容器中的html文本,外层容器是不确定的标签
var str="<div><p>这是html文本</p></div>"; var pattern=/<([a-zA-Z]+)>(.*?)</1>/;//1代表闭合标签,必须与开始标签相同 console.log(pattern.exec(str));//["<div><p>这是html文本</p></div>", "div", "<p>这是html文本</p>", index: 0, input: "<div><p>这是html文本</p></div>", groups: undefined]
如上,第一个分组是外层标签名,第二个分组是获取到的内层html
.exec 返回的数组:
匹配到的结果
分组依次返回
index 匹配到的位置索引
input 被匹配的字符串
位置匹配之首尾匹配
^ 字符串的开始
$ 字符串的结束
var str="js"; var pattern=/^js/; console.log(pattern.exec(str));//["js", index: 0, input: "js", groups: undefined] var str="html js"; var pattern=/^js/; console.log(pattern.exec(str));//null
匹配全是数字
var str="123mm567"; var pattern=/^d+$/; console.log(pattern.exec(str));//null if(pattern.test(str)){ alert("全是数字"); }else{ alert("不全是数字");//不全是数字 }
反向思考,匹配不是数字
var str="123mm567"; var pattern=/D/; console.log(pattern.exec(str));//["m", index: 3, input: "123mm567", groups: undefined] if(!pattern.test(str)){ alert("全是数字"); }else{ alert("不全是数字");//不全是数字 }
位置匹配之单词边界匹配
单词边界
非单词边界 B
var str="js html"; var pattern=/js/; console.log(pattern.exec(str));//["js", index: 0, input: "js html", groups: undefined] var str="@@@js@@@";//@也属于单词边界 var pattern=/js/; console.log(pattern.exec(str));//["js", index: 0, input: "js html", groups: undefined]
实现可兼容IE低版本的 getElementsByClassName()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <ul> <li class="odd1 odd odd2">1</li> <li class="even">2</li> <li class="odd">3</li> <li class="even">4</li> </ul> <script> function getByClass(className,node){ //高版本浏览器 if(document.getElementsByClassName(className)){ return document.getElementsByClassName(className) }else{ //IE低版本浏览器 var node=node || document; var arr=[]; var elements=node.getElementsByTagName("*");//获取所有元素 //注意,使用构造函数创建正则,其中的转义字符需要进行双重转义 var pattern=new RegExp("(^|\s+)"+className+"($|\s+)"); for(var i=0;i<elements.length;i++){ //匹配className if(pattern.test(elements[i].className)){ arr.push(elements[i]); } } return arr; } } var odds=getByClass("odd"); for(var i=0;i<odds.length;i++){ odds[i].style.background="pink"; } var evens=getByClass("even"); for(var i=0;i<evens.length;i++){ evens[i].style.background="#abcdef"; } </script> </body> </html>
使用单词边界的思路也可实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <ul> <li class="odd1 odd odd2">1</li> <li class="even">2</li> <li class="odd">3</li> <li class="even">4</li> </ul> <script> function getByClass(className,node){ //高版本浏览器 if(document.getElementsByClassName(className)){ return document.getElementsByClassName(className) }else{ //IE低版本浏览器 var node=node || document; var arr=[]; var elements=node.getElementsByTagName("*");//获取所有元素 //注意,使用构造函数创建正则,其中的转义字符需要进行双重转义 var pattern=new RegExp("\b"+className+"\b"); for(var i=0;i<elements.length;i++){ //匹配className if(pattern.test(elements[i].className)){ arr.push(elements[i]); } } return arr; } } var odds=getByClass("odd"); for(var i=0;i<odds.length;i++){ odds[i].style.background="pink"; } var evens=getByClass("even"); for(var i=0;i<evens.length;i++){ evens[i].style.background="#abcdef"; } </script> </body> </html>
前瞻性匹配 (?= )
var str="javascript"; var pattern=/java(?=script)/;//如果java后面跟的是script,那么匹配出java console.log(pattern.test(str));//true var str="java"; var pattern=/java(?=script)/;//如果java后面跟的是script,那么匹配出java console.log(pattern.test(str));//false
负前瞻性匹配 (?!)
var str="javascript"; var pattern=/java(?!script)/;//如果java后面跟的是script,那么不匹配出java console.log(pattern.test(str));//false var str="java"; var pattern=/java(?!script)/;//如果java后面跟的不是script,那么匹配出java console.log(pattern.test(str));//true
RegExp 对象的实例方法
其中的转义字符需要进行双重转义
var pattern=new RegExp(""); console.log(pattern);// // var pattern=new RegExp("\b"); console.log(pattern);// //
因此,如果是 ,直面量方式转义为 \,构造函数双重转义为 \\
var pattern=new RegExp("\\"); console.log(pattern);// /\/
pattern 就是正则实例的对象,pattern 拥有的方法就是实例方法
如: .test() .exec()
var str="js js js"; var pattern=/js/; console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] var pattern=/js/g; console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// ["js", index: 3, input: "js js js", groups: undefined] console.log(pattern.exec(str));// ["js", index: 4, input: "js js js", groups: undefined] console.log(pattern.exec(str));// null console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined]
如上,exec 有一个属性,叫 lastIndex,默认是0
如果设置为全局匹配,则 lastIndex 是上一次匹配的结束位置的下一位
如果匹配到为 null,就会自动重置为0,再次进行下一轮
分组之后也能捕获
var str="js js js"; var pattern=/(j)s/; console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined] var pattern=/(j)s/g; console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined] console.log(pattern.exec(str));// (2) ["js", "j", index: 3, input: "js js js", groups: undefined] console.log(pattern.exec(str));// (2) ["js", "j", index: 6, input: "js js js", groups: undefined] console.log(pattern.exec(str));// null console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]
实例:
var str="1.js 2.js 3.js"; var pattern=/js/g; var total=0;//出现的总次数 var result; while((result=pattern.exec(str))!=null){//先赋值再进行判断 total++; console.log(result[0]+"第"+total+"次出现的位置是:"+result.index); } console.log("总共出现了"+total+"次");
test 与 exec 类似原理
var str="js js js"; var pattern=/js/; console.log(pattern.test(str));//true console.log(pattern.test(str));//true console.log(pattern.test(str));//true console.log(pattern.test(str));//true console.log(pattern.test(str));//true var pattern=/js/g; console.log(pattern.test(str));//true console.log(pattern.test(str));//true console.log(pattern.test(str));//true console.log(pattern.test(str));//false console.log(pattern.test(str));//true
.toString() 转字符串
.toLocaleString() 转本地字符串(仅限少数语言)
.valueOf() 返回正则本身
var pattern=new RegExp("a\nb"); console.log(pattern.toString()); // /a b/ 此处返回的是字面量形式的字符串 console.log(pattern.toLocaleString());// /a b/ console.log(pattern.valueOf());// /a b/ console.log(pattern.valueOf()===pattern);// true
实例属性
.ignoreCase 判断是否忽略大小写
.global 是否全局
.multiline 是否匹配到多行
.source 返回字面量正则本身
var str="js js js"; var pattern=/js/im; console.log(pattern.ignoreCase);//true console.log(pattern.global);//false console.log(pattern.multiline);//true console.log(pattern.source);//js console.log(pattern.source===pattern);//false
.lastIndex 最后一次匹配的位置的后一位
var str="js js"; var pattern=/js/; console.log(pattern.lastIndex);//0 pattern.test(str); console.log(pattern.lastIndex);//0 pattern.test(str); console.log(pattern.lastIndex);//0 pattern.test(str); console.log(pattern.lastIndex);//0 pattern.test(str); console.log(pattern.lastIndex);//0 var pattern=/js/g; console.log(pattern.lastIndex);//0 pattern.test(str); console.log(pattern.lastIndex);//2 pattern.test(str); console.log(pattern.lastIndex);//5 pattern.test(str); console.log(pattern.lastIndex);//0 匹配不到时重置到0 pattern.test(str); console.log(pattern.lastIndex);//2
构造函数属性 RegExp.
.input 待匹配的字符串 = $_
.lastMatch 最近一次匹配到的字符 = $&
.leftContext 最近一次匹配时左边的字符 = $`
.rightContext 最近一次匹配时右边的字符 = $'
.lastParen 最近一次匹配到的子选项(分组中的内容) = $+
.$n 捕获分组
var str="js js"; var pattern=/(j)s/; pattern.exec(str); //待匹配的字符串 console.log(RegExp.input);//js js console.log(RegExp["$_"]);//js js //最近一次匹配到的字符 console.log(RegExp.lastMatch);//js console.log(RegExp["$&"]);//js //最近一次匹配时左边的字符 console.log(RegExp.leftContext);//空 console.log(RegExp["$`"]);//空 //最近一次匹配时右边的字符 console.log(RegExp.rightContext);// js console.log(RegExp["$'"]);// js //最近一次匹配到的子选项(分组中的内容) console.log(RegExp.lastParen);// j console.log(RegExp["$+"]);// j //捕获分组 console.log(RegExp.$1);// j
string 对象中,与正则相关的方法
str.search() 与是否全局无关,只查找一个,如果有,就返回 index
如果没有,就返回 -1
var str="js js"; var pattern=/(j)s/; console.log(str.search(pattern));//0 var pattern=/aa/; console.log(str.search(pattern));//-1
str.match()
普通匹配时与 exec 相同
全局匹配时:直接返回所有匹配的元素,分组会失效
var str="js js"; var pattern=/(j)s/; console.log(str.match(pattern));//(2) ["js", "j", index: 0, input: "js js", groups: undefined] var pattern=/aa/; console.log(str.match(pattern));//null var pattern=/(j)s/g; console.log(str.match(pattern));//(2) ["js", "js"] var pattern=/aa/; console.log(str.match(pattern));//null
str.match( pattern )
非全局匹配时才能返回分组中的内容
全局匹配时会返回所有匹配到的字符
m 和 g 组合,结合首尾匹配,体现
var str="1.js 2.js 3.js"; var pattern=/js$/g;//匹配行尾的js,默认是一行 console.log(str.match(pattern));//["js"] var pattern=/js$/mg;//匹配行尾的js,默认是多行 console.log(str.match(pattern));//(3) ["js", "js", "js"]
str.split() 字符串分割,转为数组
var str="1,2,3"; console.log(str.split(","));//(3) ["1", "2", "3"] var str="1, 2 , 3"; var pattern=/s*,s*/g; console.log(str.split(pattern));//(3) ["1", "2", "3"]
str.replace()
var str="i love js js"; console.log(str.replace("js","html"));//i love html js var pattern=/js/g; console.log(str.replace(pattern,"html"));//i love html html
replace 替换时间格式
var str="2020-2-15"; var pattern=/-/g; console.log(str.replace(pattern,"/"));//2020/2/15
使用 $n 进行分组引用
var str="i love pink"; var pattern=/(pink)/g; document.write(str.replace(pattern,"<span style='background:pink'>$1</span>"));
敏感词的过滤
var str="中国军队和阿扁一起办证"; var pattern=/国军|阿扁|办证/g; document.write(str.replace(pattern,"*"));//中*队和*一起*
一个文字对应一个 * 号
$0 是每次匹配到的内容
var str="中国军队和阿扁一起办证"; var pattern=/国军|阿扁|办证/g; document.write(str.replace(pattern,function($0){ console.log($0); var result=""; for(var i=0;i<$0.length;i++){ result+="*"; } return result; }));//中**队和**一起**
f5 浅刷新
ctrl+f5 深度刷新
常用的正则表达式:
1、QQ号:
全数字 首位不是0 最少5位 (目前最多11位,以后可能会扩增)
/^[1-9]d{4,10}$/ /^[1-9]d{4,}$/
2、用户名、昵称
2-18位 中英文数字及下划线组成
/^[ue400-u9fa5w]{2,18}$/ /^[ue400-u9fa5a-zA-Z0-9_]{2,18}$/
3、密码
6-16位 不能有空白符 区分大小写
/^S{6,16}$/
4、去除字符串首尾的空白字符
首先是去除首部或者尾部
var str=" cyy "; console.log("|"+str+"|");// | cyy | var pattern=/^s+/; str=str.replace(pattern,"");//替换左边空白符 var pattern2=/s+$/; /* 这里使用 s+ 比使用 s* 效率高 s* 无论如何都会进行替换,哪怕没有空白符 s+ 只在有空白符的时候进行替换,否则直接返回 */ str=str.replace(pattern2,"");//替换右边空白符 console.log("|"+str+"|");// |cyy|
同时去除首尾空白符
var str=" cyy "; console.log("|"+str+"|");// | cyy | var pattern=/^s+|s+$/g; str=str.replace(pattern,"");//替换左右空白符 console.log("|"+str+"|");// |cyy|
var str=" cyy "; console.log("|"+str+"|");// | cyy | function trim(str){ return str.replace(/^s+/,"").replace(/s+$/,""); } console.log("|"+trim(str)+"|");// |cyy|
5、转驼峰
str.replace(pattern, 要替换的内容) 第二个参数可以是一个匿名函数的返回值
匿名函数的参数中,第一个参数是匹配的内容,第二个参数开始是分组捕获的内容
var str="background-color"; var pattern=/-([a-z])/gi;// 此处匹配到-c //因为在匹配的结果中,第一个参数是匹配的内容,第二个参数开始是分组的内容 //因此此处all为 -c letter为 c //也可以用$0 $1表示 console.log(str.replace(pattern,function(all,letter){ return letter.toUpperCase(); }));// backgroundColor console.log(str.replace(pattern,function($0,$1){ return $1.toUpperCase(); }));// backgroundColor // 封装转驼峰函数 function toCamelCase(str){ return str.replace(pattern,function($0,$1){ return $1.toUpperCase(); }); } console.log(toCamelCase(str));//backgroundColor
6、匹配HTML标签
匹配开始标签和结束标签,标签中的内容不要
var str="<p style='color:red' class='active'>这是段落</p>"; var pattern=/<.+?>/g;//非贪婪模式匹配两个尖括号之间的内容 console.log(str.match(pattern)); var pattern=/<[^>]+>/g;//两个尖括号内部,没有匹配到结束的尖括号 console.log(str.match(pattern));
7、email 邮箱
cyy@qq.com.cn
cyy_1@qq.com
cyy.com@qq.com.cn
/^(w+.)*w+@(w+.)+[a-z]$/i
8、URL
/* http://www.baicu.com http或者https 可有可无 除了 : 和 / ,其他的都属于主机名 */ //简化版,要求不高 /^(https?://)?[^:/]+(:d+)?(/.*)?$/ //精确版 //协议: http:// https:// ftp:// mailto:// file:/// //匹配主机名 www.baidu.com //可以有连字符,但是连字符不能作为开头和结尾 /^([a-z0-9]+.|[a-z0-9]+-[a-z0-9]+.)*[a-z]+$/i
可以把经常用的正则存到一个对象中,如:
var regExp={ "chinese":/[u4e00-u9fa5]/, "qq":/^[1-9]d{4,}$/, ... }
制作一个简易的正则测试工具
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin:0; padding:0; } body{ background:#abcdef; } .wrap{ width:1000px; margin:10px auto; font-size:14px; } .container{ width:650px; float:left; } .wrap h1{ text-align: center; font-size:20px; } .textBox{ border:1px solid #fff; padding:5px; width:638px; height:130px; border-radius:5px; resize:none;/*不允许拖拽输入框*/ margin-top:15px; } div.textBox{ background:#eee; } .pattenInput{ width:180px; padding:5px; border:1px solid #fff; border-radius:5px; } .matchBtn{ width:100px; text-align: center; padding:5px; background-color: pink; border:none; border-radius:5px; margin-left:10px; } #matchResult span, #replaceResult span{ background:orange; } .list{ width:280px; float:right; border:1px solid #fff; border-radius:5px; background-color: #fff; margin-top:14px; padding:20px; } .list dt{ font-weight:bold; font-size:18px; margin-bottom:10px; color:#333; } .list dd{ height:40px; line-height:40px; } .list dd a{ display: block; text-decoration: none; color:#333; } .list dd a:hover{ color:orange; } .footer{ text-align: center; } .footer{ zoom:1; } .wrap::after{ content:""; display: block; clear:both; } .footer span{ color:orange; } </style> </head> <body> <div class="wrap"> <h1>正则表达式测试工具</h1> <div class="container"> <textarea id="userInput" class="textBox" placeholder="请输入需要匹配的文本"></textarea> <p> 正则表达式:<input type="text" placeholder="请输入正则表达式" class="pattenInput" id="pattenInput"> <input type="checkbox" name="modifier" value="i">忽略大小写 <input type="checkbox" name="modifier" value="g">全局匹配 <input type="checkbox" name="modifier" value="m">多行匹配 <input type="button" value="测试匹配" id="matchBtn" class="matchBtn"> </p> 匹配结果: <!-- 原来使用textarea,内部文本不允许加标签,因此换为div --> <div id="matchResult" class="textBox" placeholder="请输入需要匹配的文本"></div> <p> 替换文本:<input type="text" placeholder="请输入替换文本" class="pattenInput" id="replaceInput"> <input type="button" value="正则替换" id="replaceBtn" class="matchBtn"> </p> 替换结果: <!-- 原来使用textarea,内部文本不允许加标签,因此换为div --> <div id="replaceResult" class="textBox" placeholder="请输入需要匹配的文本"></div> </div> <dl class="list" id="list"> <dt>常用正则表达式</dt> <dd><a href="javascript:void(0)" title="[u4e00-u9fa5]">匹配中文字符</a></dd> <dd><a href="javascript:void(0)" title="[1-9]d{4,}">QQ</a></dd> </dl> </div> <p class="footer">本程序由<span>cyy</span>制作,欢迎大家使用~</p> <script> var userInput=document.getElementById("userInput"); var pattenInput=document.getElementById("pattenInput"); var modifiers=document.getElementsByName("modifier"); var matchBtn=document.getElementById("matchBtn"); var matchResult=document.getElementById("matchResult"); var replaceInput=document.getElementById("replaceInput"); var replaceBtn=document.getElementById("replaceBtn"); var replaceResult=document.getElementById("replaceResult"); var links=document.getElementById("list").getElementsByTagName("a"); var pattern=""; var modifier=""; //处理模式修饰符 for(var i=0;i<modifiers.length;i++){ modifiers[i].onclick=function(){ modifier="";//每次点击后先清空原来的 for(var j=0;j<modifiers.length;j++){ if(modifiers[j].checked){ modifier+=modifiers[j].value; } } } } //点击按钮进行匹配 matchBtn.onclick=function(){ //没有输入文本 if(!userInput.value){ alert("请输入待匹配的文本~"); userInput.focus();//获取光标 return;//不再执行下面的脚本 } //没有输入正则 if(!pattenInput.value){ alert("请输入待匹配的文本~"); pattenInput.focus(); return; } pattern=new RegExp("("+pattenInput.value+")",modifier); console.log(userInput); matchResult.innerHTML=pattern.exec(userInput.value) ? userInput.value.replace(pattern,"<span>$1</span>"): "(没有匹配到哦~)"; } //点击按钮进行替换 replaceBtn.onclick=function(){ //没有输入文本 if(!userInput.value){ alert("请输入待匹配的文本~"); userInput.focus();//获取光标 return;//不再执行下面的脚本 } //没有输入正则 if(!pattenInput.value){ alert("请输入待匹配的文本~"); pattenInput.focus(); return; } //没有输入替换文本 if(!replaceInput.value){ alert("请输入要替换的文本~"); replaceInput.focus(); return; } pattern=new RegExp("("+pattenInput.value+")",modifier); replaceResult.innerHTML=userInput.value.replace(pattern,"<span>"+replaceInput.value+"</span>"); } //点击右侧快捷正则 for(var i=0;i<links.length;i++){ links[i].onclick=function(){ pattenInput.value=this.title;//this指当前点击的元素 } } </script> </body> </html>
补充:
() 分组可以捕获内容
(?:) 不参与捕获
$1 $2... 分别表示捕获到的内容
如何获取捕获到的内容:
exec() 返回的数组中,第一个是匹配到的内容,第二个开始是捕获的内容
/1/ 模式中,直接在正则中引用捕获到的内容
replace() 的第2个参数中,$1 (如果第2个参数是匿名函数,这个匿名函数的第一个参数是匹配到的内容,第二个参数开始是捕获到的内容)
RegExp.$1