假设用户需要在HTML表单中填写姓名、地址、出生日期等。那么在将表单提交到服务器进一步处理前,JavaScript程序会检查表单以确认用户确实输入了信息并且这些信息是符合要求的。
一.什么是正则表达式
正则表达式(regular expression)是一个描述字符模式的对象。ECMAScript的RegExp类表示正则表达式,而String和RegExp都定义了使用正则表达式进行强大的模式匹配和文本检索与替换的函数。
正则表达式主要用来验证客户端的输入数据。用户填写完表单单击按钮之后,表单就会被发送到服务器,在服务器端通常会用 PHP、ASP.NET 等服务器脚本对其进行进一步处理。因为客户端验证,可以节约大量的服务器端的系统资源,并且提供更好的用户体验。
二.创建正则表达式
创建正则表达式和创建字符串类似,创建正则表达式提供了两种方法,一种是采用new运算符,另一个是采用字面量方式。
1.两种创建方式
模式修饰符的可选参数含义
i忽略大小写
g全局匹配
m多行匹配
方式一:new运算符
var box = new RegExp('Box'); //第一个参数是模式字符串
alert(box); //打印出:/Box/(两个反斜杠是正则表达式的字面量表示法)
var box = new RegExp('Box', 'gi'); //第二参数可选,模式修饰符
alert(box); //打印出:/Box/gi
方式二:字面量方式
var box = /Box/; //使用字面量方式的正则
alert(box);
var box = /Box/ig; //字面量正则,带修饰符的
alert(box);
2.测试正则表达式
RegExp对象包含两个方法:test()和exec(),功能基本相似,用于测试字符串匹配。test()方法在字符串中查找是否存在指定的正则表达式并返回布尔值,如果存在则返回 true,不存在则返回false。exec()方法也用于在字符串中查找指定正则表达式,如果exec()方法执行成功,则返回包含该查找字符串的相关信息数组。如果执行失败,则返回null。
RegExp对象的方法方法功能:
test在字符串中测试模式匹配,返回true或false
(1)使用new运算符方式的test()匹配:
var pattern = new RegExp('Box'); //创建正则模式
var str = 'box'; //创建要比对的字符串
alert(pattern.test(str)); //返回的是false,大小写不一致
var pattern = new RegExp('Box', 'i'); //创建正则模式,不区分大小写
var str = 'box'; //创建要比对的字符串
alert(pattern.test(str)); //通过test()方法验证是否匹配:true
(2)使用字面量运算符方式的test()匹配:
var pattern = /Box/i; //创建正则模式,不区分大小写
var str = 'box';
alert(pattern.test(str)); //true
(3)一句话使用test匹配
alert(/Box/i.test('box')); //true,一句话匹配
(4)字符串使用test匹配
var pattern = /Box/i; //不区分大小写匹配
var str = 'This is a box!'; //创建要比对的字符串
alert(pattern.test(str)); //字符串中是否包含模式中的正则
//This is a box! 中是否包含不区分大小写的Box
exec在字符串中执行匹配搜索,返回结果数组
var pattern=/Box/i;
var str='box';
alert(typeof pattern.exec(str)); //返回的是数组,有就返回数组的值,没有就返回null
var pattern = /Box/i;
var str = 'ssss';
alert(pattern.exec(str)); //如果没有匹配到,就返回null
3.使用字符串的正则表达式方法
除了test()和exec()方法,String对象也提供了4个使用正则表达式的方法。
String对象中的正则表达式方法方含义:
(1)match(pattern)返回pattern中的子串或null
使用match方法获取获取匹配数组
var pattern = /Box/i; //没有开启全局
var str = 'This is a Box! That is a Box!';
alert(str.match(pattern)); //匹配到第一个字符串返回数组:Box
var pattern = /Box/i; //没有开启全局
var str = 'This is a Box! That is a Box!';
var a = str.match(pattern);
alert(a[0]); //证明了是数组:Box
var pattern = /Box/ig; //开启了全局
var str = 'This is a Box! That is a Box!';
alert(str.match(pattern)); //将所有匹配的字符串组合成数组返回:Box Box
(2)replace(pattern, replacement)用replacement替换pattern
使用search来查找匹配数据
var pattern=/Box/i;
var str='This is a Box! That is a Box!';
alert(str.search(pattern)); //返回的第一个匹配的位置:10
注意:因为search方法查找到即返回,也就是说无需g全局
var pattern = /xox/i;
var str = 'This is a Box! That is a Box!';
alert(str.search(pattern)); //找不到匹配,返回-1
(3)search(pattern)返回字符串中pattern开始位置
使用replace替换匹配到的数据
var pattern=/Box/i; //没有开启全局
var str = 'This is a Box! That is a Box!';
alert(str.replace(pattern,'Tom')); //返回替换后的字符串,只限第一个:This is a Tom! That is a Box!
var pattern=/Box/ig; //开启全局
var str = 'This is a Box! That is a Box!';
alert(str.replace(pattern,'Tom')); //返回替换后的字符串,所有匹配都会被替换:his is a Tom! That is a Tom!
(4)split(pattern)返回字符串按指定pattern拆分的数组
使用split拆分成字符串数组
var pattern = /!/ig;
var str = 'This is a Box! That is a Box!';
alert(str.split(pattern)); //将!拆开分组成数组:This is a Box,That is a Box,
alert(str.split(pattern).length); //产生数组长度:3
RegExp对象的静态属性:
使用静态属性:
var pattern = /(g)oogle/ig;
var str = 'This is a google!';
pattern.test(str); //必须执行一下,静态属性才有效
alert(RegExp.input); //This is google!
alert(RegExp.leftContext); //匹配到的字符串的前子串:This is
alert(RegExp.rightContext); //匹配到的字符串的右子串:!
alert(RegExp.lastMatch); //最后一次匹配到的:google
alert(RegExp.lastParen); //()分组里打出来:g
alert(RegExp.multiline); //false
注意:Opera不支持input、lastMatch、lastParen和multiline属性。IE不支持multiline属性。
所有的属性可以使用短名来操作。RegExp.input可以改写成RegExp['$_'],依次类推。但RegExp.input比较特殊,它还可以写成RegExp.$_。
RegExp对象的实例属性
使用实例属性
var pattern = /google/ig;
alert(pattern.global); //true,是否全局了
alert(pattern.ignoreCase); //true,是否忽略大小写
alert(pattern.multiline); //false,是否支持换行
alert(pattern.lastIndex); //0,下次的匹配位置
alert(pattern.source); //google,正则表达式的源字符串
var pattern=/google/g;
var str='google google google';
pattern.test(str); //google,匹配第一次
alert(pattern.lastIndex); //6,第二次匹配的位
注意:
以上基本没什么用。并且lastIndex在获取下次匹配位置上IE和其他浏览器有偏差,主要表现在非全局匹配上。lastIndex还支持手动设置,直接赋值操作。
三.获取控制
正则表达式元字符是包含特殊含义的字符。它们有一些特殊功能,可以控制匹配模式的方式。反斜杠后的元字符将失去其特殊含义。
1.字符类:单个字符和数字
(1)使用点元字符.匹配除换行符外的任意字符
var pattern=/g..gle/; //点符号表示匹配除了换行符外的任意字符
var str='g12gle';
alert(pattern.test(str)); //true
(2)[a-z0-9]匹配括号中的字符集中的任意字符
字母小写
var pattern = /[a-z]oogle/; //[a-z]表示26个小写字母,任意一个都可以匹配
var str = 'google';
alert(pattern.test(str)); //true
字母大写
var pattern = /[A-Z]oogle/; //[A-Z]表示26个大写字母,任意一个都可以匹配
var str = 'Google';
alert(pattern.test(str)); //true
数字之间
var pattern=/[0-9]*oogle/; //[0-9]*,表示0次,一次,或者多次
var str ='44444oogle';
alert(pattern.test(str)); //true
数字字母
var pattern=/[a-zA-Z0-9]oogle/; //[a-zA-Z0-9]表示匹配大小写的a-zA-Z0-9
var str='7oogle';
alert(pattern.test(str)); //true
(3)[^a-z0-9]匹配任意不在括号中的字符集中的字符
var pattern=/[^a-zA-Z0-9]oogle/; //[^0-9]表示非0-9的任意字符
var str='_oogle';
alert(pattern.test(str)); //true
(4)\d匹配数字
var pattern = /\doogle/; //\d表示[0-9]
var str = 'aoogle';
alert(pattern.test(str)); //false
(5)\D匹配非数字,同[^0-9]相同
var pattern = /\Doogle/; //\D表示[^0-9]
var str = '1oogle';
alert(pattern.test(str)); //false
(6)\w匹配字母和数字及_
var pattern = /\woogle/; //\w表示[a-zA-Z_]
var str = '-oogle';
alert(pattern.test(str)); //false
(7)\W匹配非字母和数字及_
var pattern = /\Woogle/; //\W表示[^a-zA-Z_]
var str = '-oogle';
alert(pattern.test(str)); //true
2.字符类:空白字符
(1)\0匹配null字符
(2)\b匹配空格字符
var pattern = /google\b/; //\b表示到达边界
var str = 'googleabc';
alert(pattern.test(str)); //false,b没有到达边界
(3)\f匹配进纸字符
(4)\n匹配换行符
(5)\r匹配回车字符
(6)\t匹配制表符
(7)\s匹配空白字符、空格、制表符和换行符
var pattern = /goo\sgle/; //\s表示空格匹配
var str = 'goo gle';
alert(pattern.test(str)); //true
(8)\S匹配非空白字符
3.字符类:锚字符
(1)^ 行首匹配
var pattern = /^[0-9]oogle/; //这个^符号,是加在/后面的而不是[]里面的
var str = '444oogle';
alert(pattern.test(str)); //false
var pattern = /^[0-9]+oogle/; //+号,可以匹配一个或者多个
var str = '444oogle';
alert(pattern.test(str)); //true
(2)$行尾匹配
var pattern = /^[a-z]oogl[0-9]$/; //^强制首匹配,$强制尾匹配
var str = 'googl5';
alert(pattern.test(str)); //true
(3)\A 只有匹配字符串开始处
(4)\b 匹配单词边界,词在[]内时无效
(5)\B 匹配非单词边界
(6)\G 匹配当前搜索的开始位置
(7)\Z 匹配字符串结束处或行尾
(8)\z 只匹配字符串结束处
4.字符类:重复字符
(1)x?匹配0个或1个x
var pattern=/go?gle/; //o?,表示1个,或者0个
var str='google';
alert(pattern.test(str)); //false
var pattern = /g.?gle/; //.?,表示1个,或者0个的任意字符
var str = 'gbbgle';
alert(pattern.test(str)); //false
(3)x*匹配0个或任意多个x
var pattern=/go*gle/; //o*,表示0个,1个,或者多个o
var str ='goooogle';
alert(pattern.test(str)); //true
(4)x+匹配至少一个x
var pattern = /go+gle/; //o+,表示1个,或者多个
var str = 'google';
alert(pattern.test(str)); //true
(5)(xyz)+ 匹配至少一个(xyz)
(6)x{m,n}匹配最少m个、最多n个x
范围限定
var pattern = /go{2,4}gle/; //o{2,4}表示匹配o2-4次,包含2和4
var str = 'google';
alert(pattern.test(str)); //true
固定限定
var pattern = /go{3}gle/; //o{3},表示只能限定为3个
var str = 'goooogle';
alert(pattern.test(str)); //false
多少以上限定
var pattern = /go{3,}gle/; //o{3,},表示为3个或3个以上
var str = 'goooooooooogle';
alert(pattern.test(str)); //true
5.字符类:替代字符
(1)this|where|logo匹配this或where或logo中任意一个
var pattern = /google|baidu|bing/; //|表示匹配或选择模式
var str = 'this is a bing'; //匹配概念,不是相等,包含意思
alert(pattern.test(str)); //true
6.字符类:记录字符
(1)(string)用于反向引用的分组
var pattern=/google{4,8}$/; //表示e的4-8次
var str='googleeee';
alert(pattern.test(str)); //true
var pattern = /(google){4,8}$/; //分组,可以看着一个字符
var str = 'googlegooglegooglegoogle'; //表示google4-8次
alert(pattern.test(str)); //true
(2)\1或$1匹配第一个分组中的内容
var pattern = /8(.*)8/;
var str = 'This is a 8google8';
str.match(pattern);
alert(RegExp.$1); //RegExp.$1表示获取模式中第一个分组对应的匹配字符串google
var pattern = /8(.*)8/;
var str = 'This is a 8xixi8';
document.write(str.replace(pattern,'<strong>$1</strong>')); //$1表示分组获取字符串匹配到的内容:This is a xixi
(3)\2或$2匹配第二个分组中的内容
var pattern=/(.*)\s(.*)/;
var str = 'google baidu';
alert(str.replace(pattern,'$2 $1')); //位置交换:baidu google
(4)\3或$3匹配第三个分组中的内容
7.关于贪婪和惰性
(1)+贪婪模式
var pattern = /[a-z]+/; //这里使用了贪婪模式
var str = 'abcdefj';
alert(str.replace(pattern,'1')); //所有的字符串变成了1
(1)+?惰性模式
var pattern = /[a-z]+?/; /使用惰性模式
var str = 'abcdefj';
alert(str.replace(pattern, '1')); //只有第一个字符变成了1,后面没有匹配
开启全局并且使用惰性模式
var pattern = /[a-z]+?/g; //开启全局,并且使用惰性模式
var str = 'abcdefj';
alert(str.replace(pattern, '1')); //每一个字母替换成了1
(2)?使用贪婪
(2)??使用惰性
(3)*使用贪婪
var pattern=/8(.*)8/; //使用了贪婪,
var str ='8google8 8google8 8google8'; //匹配到了google8 8google8 8google
document.write(str.replace(pattern,'<strong>$1</strong>')); //结果:<strong>google8 8google8 8google</strong>
(3)*?使用惰性
var pattern=/8(.*?)8/g; //使用了惰性,开启全局
var str = '8google8 8google8 8google8';
document.write(str.replace(pattern,'<strong>$1</strong>'));
//这次结果正确了
//<strong>google</strong>
//<strong>google</strong>
//<strong>google</strong>
另一种惰性方式
var pattern=/8([^8]*)8/g; //另一种惰性,屏蔽了8的匹配,也就是两边包含字符
var str ='8google8 8google8 8google8';
document.write(str.replace(pattern,'<strong>$1</strong>'));
//结果:
//<strong>google</strong>
//<strong>google</strong>
//<strong>google</strong>
(4)使用贪婪{n}
(4)使用惰性{n}?
(5)使用贪婪{n,}
(5)使用惰性{n,}?
(6)使用贪婪{n,m}
(6)使用惰性{n,m}?
8.使用exec返回数组
var pattern = /^[a-z]+\s[0-9]{4}$/;
var str = 'google 2012';
alert(pattern.exec(str)); //返回一个包含字符串的数组google 2012
(1)只匹配字母
var pattern = /^[a-z]+/; //只匹配到字母
var str = 'google 2012';
alert(pattern.exec(str)); //只返回google的字符串数组
(2)使用了分组
var pattern=/^([a-z]+)\s([0-9]{4})$/; //使用了分组
var str='google 2017';
var a=pattern.exec(str);
alert(a.length); //长度:3
alert(a[0]); //a[0],返回匹配到的整个字符串:google 2017
alert(a[1]); //a[1],返回匹配到的第一个分组的字符串:google
alert(a[2]); //a[2],返回匹配到的第二个分组的字符串2017
9.捕获性分组和非捕获性分组
(1)捕获性分组
var pattern=/(\d+)([a-z])/; //这个叫做捕获性分组,所有的分组都捕获返回
var str='123abc';
var a=pattern.exec(str);
//打印结果
//a[0]返回123a
//a[1]返回123
//a[2]返回a
(2)非捕获性分组
var pattern=/(\d+)(?:[a-z])/; //a[2]非捕获性分组不显示,只要在不需要捕获返回的分组加上?:
var str='123abc';
alert(pattern.exec(str));
//打印结果
//a[0]返回123a
//a[1]返回123
10.使用分组嵌套
var pattern=/(a?(b?(c?)))/; //嵌套分组,从外往内获取
var str='abc';
alert(pattern.exec(str)); //打印结果:abc,abc,bc,c
//第一步:a[0],整个匹配到的字符串abc
//第二步:a[1],匹配第一个分组(a?(b?(c?))),abc
//第三步:a[2],匹配第二个分组(b?(c?), bc
//第四步:a[3],匹配第三个分组(c?),c
11.使用前瞻捕获
var pattern=/goo(?=gle)/; //goo后面必须是gle才能返回goo,这里一定要注意,返回的是goo,而不是google
var str ='google';
alert(pattern.exec(str)); //返回的是goo,而不是google,这是前瞻性捕获
12.使用特殊字符匹配
var pattern=/\[/; //用\符号来转义正则里的特殊字符,才能匹配
var str ='[';
alert(pattern.test(str)); //匹配结果:true
13.使用换行模式
var pattern=/^\d+/gm; //限定了首匹配,并且开启换行模式
var str='1.baidu\n2.google\n3.bing';
alert(str.replace(pattern,'#')); //
四.常用的正则
1.检查邮政编码
var pattern=/[1-9][0-9]{5}/;
var str='This is 100010!'; //必须是6位,必须是数字,第一位不能为0
alert(pattern.test(str)); //true
2.检查文件压缩包
var pattern= ^[\w\-]+\.zip|gz|rar/; //\w+,包含-号,再加上^来限定首字符开始匹配
var str='2-13.zip'; //文件名:字母_数字.zip,gz,rar
alert(pattern.test(str)); //true
3.删除多余空格
var pattern=/\s/g; //g必须全局,才能全部匹配
var str='111 222 333 555';
alert(str.replace(pattern,'')); //把空格匹配成无空格结果:111222333555
4.删除首尾空格
(1)方式一:两次正则
var pattern=/^\s+/; //强制首
var str=' goo gle ';
var result=str.replace(pattern,'');
pattern=/\s+$/; //强制尾
result=result.replace(pattern,''); //生成过后的
alert('|'+result+'|'); //输出结果:|goo gle|
(2)方式二:使用了非贪婪捕获
var pattern =/^\s+(.+?)\s+$/; //(.+)是贪婪模式,惰性模式
var str=' goo gle ';
var result=pattern.exec(str)[1];
alert('|'+result+'|'); //输出结果:|goo gle|
(3)方式三:使用的分组获取
var pattern =/^\s+(.+?)\s+$/;
var str=' goo gle ';
var result=str.replace(pattern,'$1'); //使用的分组获取
alert('|'+result+'|'); //输出结果:|goo gle|
5.简单的电子邮件验证
var pattern=/^([\w\.\-]+)@([\w\-]+)\.([a-zA-Z]{2,4})$/;
var str='xixi.com@mail.com';
alert(pattern.test(str));